如何在 shell 脚本中运行别名?

Pau*_*aul 148 bash scripts alias

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

alias petsc="~/petsc-3.2-p6/petsc-arch/bin/mpiexec"  
Run Code Online (Sandbox Code Playgroud)

这使我mpiexec可以通过键入以下内容在命令提示符下轻松执行此文件:

petsc myexecutable
Run Code Online (Sandbox Code Playgroud)

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

./script: line 1: petsc: command not found
Run Code Online (Sandbox Code Playgroud)

我知道我可以只写mpiexec文件的完整路径,但是每次我想写一个新脚本时都写完整路径很麻烦。有没有办法可以petsc在脚本文件中使用我的别名?有没有办法可以编辑我的.bashrc.bash_profile实现这一点?

Pan*_*her 106

一些选项:

  1. 在您的 shell 脚本中使用完整路径而不是别名。

  2. 在你的 shell 脚本中,设置一个变量,不同的语法

    petsc='/home/your_user/petsc-3.2-p6/petsc-arch/bin/mpiexec'
    
    $petsc myexecutable
    
    Run Code Online (Sandbox Code Playgroud)
  3. 在脚本中使用函数。如果petsc复杂,可能会更好

    function petsc () {
        command 1
        command 2
    }
    
    petsc myexecutable
    
    Run Code Online (Sandbox Code Playgroud)
  4. 获取别名

    shopt -s expand_aliases
    source /home/your_user/.bashrc
    
    Run Code Online (Sandbox Code Playgroud)

您可能不想获取您的.bashrc.

  • OP 没有要求但与问题标题相关:第 2 点不适用于包含 `|` 的命令。在这里,使用`shopt -s expand_aliases` 和本地别名,例如`alias myalias='echo abc|rev'` - 使用前需要换行(参见`man bash` 中的ALIASES)。第 4 点:源文件可能会阻止非交互式执行,即在脚本中。寻找早期的`exit` 或`return`,例如`[ -z "$PS1" ] && return`(检查是否未设置主提示以指示非交互式shell)或者可能会检查`i` in `$-`(`$-` 包含 shell 选项,`i` 表示交互式)。有关这些变量,请参阅`man bash`。 (4认同)
  • 我喜欢选项 4。它允许我在脚本中声明和使用别名命令 (3认同)
  • 对于 4,最好使用 `.bash_aliases` 文件而不是 `.bashrc`。然后,只能获取别名。 (3认同)
  • 在第 2 点中,您没有设置别名而是一个变量。 (2认同)

enz*_*tib 86

别名已被弃用,取而代之的是 shell 函数。从bash 手册页

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

要创建一个函数并将其导出到子shell,请将以下内容放入您的~/.bashrc

petsc() {
    ~/petsc-3.2-p6/petsc-arch/bin/mpiexec "$@"
}
export -f petsc
Run Code Online (Sandbox Code Playgroud)

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

  • @Paul:我添加了 `"$@"` 只是为了处理参数。 (7认同)

ken*_*orb 19

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

例如:

$ alias foo="echo test"
$ echo ${BASH_ALIASES[foo]}
echo test
$ echo `${BASH_ALIASES[foo]}` bar
test bar
Run Code Online (Sandbox Code Playgroud)

或者定义为变量然后使用命令替换或eval

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

alias foo="echo test"
Run Code Online (Sandbox Code Playgroud)

将其定义为:

foo="echo test"
Run Code Online (Sandbox Code Playgroud)

反而。然后通过以下任一方式执行它:

find . -type f -exec sh -c "eval $foo" \;
Run Code Online (Sandbox Code Playgroud)

或者:

find . -type f -exec sh -c "echo `$foo`" \;
Run Code Online (Sandbox Code Playgroud)


Lek*_*eyn 15

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"
    
    Run Code Online (Sandbox Code Playgroud)

    重新登录以应用这些更改

  • 创建目录~/bin


Thr*_*unt 14

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).
Run Code Online (Sandbox Code Playgroud)

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

#!/bin/bash

shopt -s expand_aliases

alias foo=bar

foo whatever
Run Code Online (Sandbox Code Playgroud)

至于我为什么要这样做:由于特殊情况,我需要欺骗 Dockerfile 使其认为它是一个 shell 脚本。


Ama*_*nez 13

您可以使用 -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..
Run Code Online (Sandbox Code Playgroud)

更多信息:

$ man bash
Run Code Online (Sandbox Code Playgroud)

  • `.bashrc` 也在非交互式 SSH 命令执行期间被读取(这就是为什么它在顶部检查交互性) (2认同)

Tim*_*imo 5

  1. .bash_aliases

    petsc {
    ~/petsc-3.2-p6/petsc-arch/bin/mpiexec "$@"
    }
    
    Run Code Online (Sandbox Code Playgroud)

    或者把函数放在.bashrc. 通常.bashrcbash存储在配置设置中。

  2. 在终端: source .bash_aliases

  3. 称它为: petsc arg(s)

优点:您不需要export -f petsc.bash_aliases. 别名已被弃用,但.bash_aliases用于函数是可以的。