我有一个可执行文件mpiexec,其完整路径是~/petsc-3.2-p6/petsc-arch/bin/mpiexec。由于我想在不同目录中执行此命令(而无需重新输入整个路径),因此我在自己的首页.bashrc文件中设置了别名:

alias petsc="~/petsc-3.2-p6/petsc-arch/bin/mpiexec"  


这允许我通过在命令提示符处键入以下命令轻松执行此mpiexec文件:

petsc myexecutable


我尝试使用新别名script作为命令编写名为petsc的外壳脚本文件。给我的Shell脚本适当的权限(使用chmod)后,我尝试运行该脚本。但是,它给了我以下错误:

./script: line 1: petsc: command not found


我知道我可以将完整的路径写入mpiexec文件,但是写完整的路径很麻烦每当我想编写一个新脚本时。有没有办法可以在脚本文件中使用别名petsc?有什么方法可以编辑我的.bashrc.bash_profile来实现这一目标?

评论

如何将别名添加到.bash_aliases?另外,如何别名绝对路径而不是别名相对路径,例如别名petsc ='/ home / user / petsc-3.2-p6 / petsc-arch / bin / mpiexec'

@nitstorm:两种解决方案似乎都无法解决...我仍然收到与以前相同的错误

相关:unix.stackexchange.com/questions/1496/…

我实际上只是使用了一个对我有用的系统链接,例如:ln -sf / usr / bin / podman .local / bin / docker

#1 楼

一些选项:


在您的shell脚本中使用完整路径而不是别名。 >
petsc='/home/your_user/petsc-3.2-p6/petsc-arch/bin/mpiexec'

$petsc myexecutable



在脚本中使用一个函数。如果petsc是复杂的

function petsc () {
    command 1
    command 2
}

petsc myexecutable



来源别名

shopt -s expand_aliases
source /home/your_user/.bashrc




您可能不想采购.bashrc,因此,IMO的前三个建议中的一个会更好。

评论


您的建议2)有效,但是我希望能够在多个shell脚本中使用相同的命令,而不必编写第一行petsc =“ ...”。有没有办法做到这一点?

– Paul
2012年1月26日18:31

听起来好像应该将命令放在更标准的位置,例如/ usr / local / bin

–豹
2012年1月26日18:35

在第2点中,您没有设置别名而是设置了变量。

– pabouk
2014年11月1日在9:58

OP并未要求它,但与问题标题有关:点2不适用于包含|的命令。在这里,使用shopt -s expand_aliases和本地别名,例如alias myalias ='echo abc | rev'-使用前需要换行(请参阅man bash中的ALIASES)。第4点:源文件可能会阻止非交互式执行,即在脚本中。寻找提早退出或返回的途径,例如[-z“ $ PS1”] &&返回(检查是否未设置主提示以指示非交互式shell),或者$-中可能存在i的检查($-包含shell选项,我的意思是交互式)。有关这些变量,请参见man bash。

–有效
2015年3月20日13:58



我喜欢选项4。它允许我在脚本中声明和使用别名命令。

–ishahak
20年8月27日在3:37

#2 楼

不赞成使用别名,而希望使用Shell函数。从bash手册页:

几乎所有目的,别名都被shell函数取代。

要创建一个函数并将其导出到子shell,请在~/.bashrc中放入以下内容:
petsc() {
    ~/petsc-3.2-p6/petsc-arch/bin/mpiexec "$@"
}
export -f petsc

然后您可以从shell脚本中自由调用命令。

评论


几乎可以正常工作...唯一的问题是我需要能够将不同的标志传递给可执行文件“ mpiexec” ...例如,我需要能够使用别名“ petsc”

– Paul
2012年1月26日18:46

@Paul:我加了“ $ @”只是为了处理参数。

– Enzotib
2012年1月26日19:47

例外之一是return。假设您正在编写一个既适用于源代码又适用于独立源代码的脚本,并且想要使用quit退出该脚本。这样的函数无法在源脚本中退出:quit(){return $ 1;}相反,您需要使用别名:alias quit = return

–陈定义
20 Sep 19'1:45



#3 楼

Shell函数和别名仅限于Shell,在已执行的Shell脚本中不起作用。您的情况的替代方法:



(如果您不麻烦使用mpiexec而不是petsc)将$HOME/petsc-3.2-p6/petsc-arch/bin添加到PATH变量中。可以通过编辑~/.profile并附加以下内容来完成:

PATH="$HOME/petsc-3.2-p6/petsc-arch/bin:$PATH"


重新登录以应用这些更改


创建目录~/bin



制作一个名为petsc的包装脚本,其中包含:

#!/bin/sh
exec ~/petsc-3.2-p6/petsc-arch/bin/mpiexec "$@"



如果程序允许为此,您可以使用以下命令跳过shellscript并建立符号链接:

ln -s ~/petsc-3.2-p6/petsc-arch/bin/mpiexec ~/bin/petsc







#4 楼

在bash 4中,您可以使用特殊变量:$BASH_ALIASES

例如:例如,而不是定义别名,例如:

$ alias foo="echo test"
$ echo ${BASH_ALIASES[foo]}
echo test
$ echo `${BASH_ALIASES[foo]}` bar
test bar


将其定义为:

alias foo="echo test"
而不是

。然后执行以下任一操作:

评论


完全不赞成使用别名,而希望使用shell函数,而这个答案是唯一应该接受的答案。甚至旧的Debian 8都有bash的版本4,因此$ {BASH_ALIASES [alias]}是一个不错的选择。否则,我必须编辑.bash_aliases的许多行才能应用其他内容。谢谢。

– m3nda
17年9月16日在9:23

确实。就我而言,它的工作方式如下:eva​​l $ {BASH_ALIASES [foo]}。甚至设法通过嵌套别名来实现,例如foo-> foo123-> / smth / real

– Mikhail Lisakov
20年5月1日在10:13



#5 楼

您可以使用-i标志强制bash将脚本作为交互式shell执行。这将告诉您的.bashrc文件定义别名和其他功能。

示例:

~ $ grep ll .bashrc
alias ll='ls -lah'
~ $ cat script.sh 
#!/bin/sh

ll
~ $ bash script.sh 
script.sh: line 3: ll: command not found
~ $ bash -i script.sh
..directory contents..


更多信息:

$ man bash


评论


.bashrc在非交互式SSH命令执行期间也会读取(这就是为什么它在顶部检查交互性的原因)

–muru
17年1月10日在13:12

#6 楼

ALIASES
   ...
   Aliases are not expanded when the shell is not interactive, unless the expand_aliases shell option is set using shopt (see the description of shopt under SHELL BUILTIN COMMANDS
   below).


因此,对于那些希望在shell脚本中使用实际别名而不是替代别名的人,真正的答案是:

#!/bin/bash

shopt -s expand_aliases

alias foo=bar

foo whatever


关于我为什么要这样做:由于异常情况,我需要欺骗Dockerfile使其认为是Shell脚本。

#7 楼



.bash_aliases中:

petsc {
~/petsc-3.2-p6/petsc-arch/bin/mpiexec "$@"
}


或将函数放在.bashrc中。通常在.bashrc中仅存储bash的配置设置。

在终端中:source .bash_aliases
调用它:petsc arg(s)


优点:不需要export -f petsc.bash_aliases中。别名已弃用,但可以使用.bash_aliases进行功能。

评论


我喜欢这种解决方案,稍后再试

– Greenonline
2015年4月24日在2:24

#8 楼


在shell脚本中使用别名。
在当前的交互式外壳中提供脚本,而不是执行脚本。

因此,如果您有一个名为script.sh的文件,其中包含使用别名的命令,只需键入:

 source script.sh
 


评论


@DavidFoerster此方法可以正常工作。使用采购脚本。或源buiiltin导致当前shell在其中执行所有命令。如果别名扩展会在其中的shell中发生。或源运行,它发生。但是,重要的是要意识到这种方法有时仅是有用的,因为经常有人需要或希望在自己的shell中使用自己的环境执行脚本。旨在以常规方式执行的Shell脚本通常不应取而代之-它们通常无法正常工作。

– Eliah Kagan
17年1月10日在9:44



@EliahKagan:谢谢。现在,我明白了答案的含义。我将添加一个解释。

–大卫·福斯特(David Foerster)
17年1月10日在9:52

#9 楼

(编辑:由于我误读了mpiexec的调用,删除了函数。)还是从$ PATH中的某个文件夹建立指向mpiexec的符号链接?或者(我的最爱)将别名放在您从调用脚本中获取的脚本中?

评论


我不能将其放入$ PATH的原因是因为我在$ PATH的另一个目录中有另一个“ mpiexec”文件。如果我将路径添加到这个新的“ mpiexec”中,它可能会尝试同时执行它们……不是吗?

– Paul
2012年1月26日19:34

无法理解为什么不简单使用“ $ @”。

– Enzotib
2012年1月26日19:49



Paul,它将尝试执行PATH中第一个而不是两者都执行的命令。

–锤子
2012年1月27日上午9:41

enzotib,啊,我误解了mpiexec的调用方式,我认为它需要所有的args作为一个。将编辑我的答案:)

–锤子
2012年1月27日在9:44

#10 楼

请使用#!/usr/bin/env sh而不是#!/usr/bin/env bash,然后它可以工作。
样本:
my.sh
 #!/usr/bin/env sh

alias k="kubectl --kubeconfig ~/shop/config"
k version
 

 ./my.sh
 

如果必须使用#!/usr/bin/env bash,请按照以下方式执行脚本:
 sh my.sh