【问题标题】:How can I define a bash alias as a sequence of multiple commands? [duplicate]如何将 bash 别名定义为多个命令的序列? [复制]
【发布时间】:2011-01-09 06:56:32
【问题描述】:

我知道如何在 bash 中配置别名,但是有没有办法为一系列命令配置别名?

也就是说,我想将一个命令更改为特定目录,然后运行另一个命令。

另外,有没有办法设置一个运行“sudo mycommand”的命令,然后输入密码?在 MS-DOS 时代,我会寻找 .bat 文件,但我不确定 linux(或者在本例中为 Mac OSX)等价物。

【问题讨论】:

    标签: linux macos alias bash


    【解决方案1】:

    您可以在别名本身中嵌入函数声明,然后是函数,如下所示:

    alias my_alias='f() { do_stuff_with "$@" (arguments)" ...; }; f'
    

    与仅声明函数本身相比,这种方法的好处是您可以放心,您的函数不会被您正在采购的其他脚本(或使用.)覆盖,这可能会使用自己的同名助手。

    例如,假设您有一个脚本 init-my-workspace.sh,您正在调用类似 . init-my-workspace.shsource init-my-workspace.sh 的脚本,其目的是设置或导出一堆环境变量(例如,JAVA_HOME、PYTHON_PATH 等)。如果您碰巧在其中也有一个函数my_alias,那么您就不走运了,因为具有相同 shell 实例的 latest 函数声明获胜。

    相反,别名具有单独的命名空间,即使在名称冲突的情况下,也会首先查找它们。因此,对于与交互使用相关的自定义,您应该只使用别名。

    最后,请注意将所有别名放在同一个位置(例如,~/.bash_aliases)的做法可以让您轻松发现任何名称冲突。

    【讨论】:

      【解决方案2】:

      你也可以写一个shell函数;例如“cd”和“ls”组合here

      【讨论】:

        【解决方案3】:

        如果逻辑变得更复杂或者如果您需要添加参数(尽管 bash 支持别名参数),您最好的选择可能是 shell 函数而不是别名。

        这个函数可以在你的 .profile 或 .bashrc 中定义。 subshel​​l 是为了避免改变你的工作目录。

        function myfunc {
           ( cd /tmp; command )
        }
        

        然后在您的命令提示符下

        $ myfunc
        

        对于第二个问题,您只需将命令添加到 /etc/sudoers(如果您完全确定自己在做什么)

        myuser           ALL = NOPASSWD: \
                            /bin/mycommand 
        

        【讨论】:

          【解决方案4】:

          您提到了 BAT 文件,所以您可能想要编写一个 shell 脚本。如果是这样,那么只需将您想要的命令逐行输入到文件中,如下所示:

          command1
          command2
          

          并要求 bash 执行文件:

          bash myscript.sh
          

          如果您希望能够直接调用脚本而无需键入“bash”,则将以下行添加为文件的第一行

          #! /bin/bash
          command1
          command2
          

          然后将文件标记为可执行文件:

          chmod 755 myscript.sh
          

          现在您可以像运行任何其他可执行文件一样运行它:

          ./myscript.sh
          

          请注意,unix 并不真正关心文件扩展名。如果您愿意,您可以简单地将文件命名为“myscript”而无需“.sh”扩展名。重要的是那条特殊的第一行。例如,如果您想用 Perl 编程语言而不是 bash 编写脚本,那么第一行将是:

          #! /usr/bin/perl
          

          第一行告诉你的 shell 调用什么解释器来执行你的脚本。

          此外,如果您现在将脚本复制到 $PATH 环境变量中列出的目录之一,那么您只需键入文件名即可从任何地方调用它:

          myscript.sh
          

          即使是制表符补全也有效。这就是为什么我通常在我的 $PATH 中包含一个 ~/bin 目录,以便我可以轻松地安装个人​​脚本。最重要的是,一旦你有一堆你习惯的个人脚本,你可以通过复制你的个人 ~/bin 目录轻松地将它们移植到任何新的 unix 机器上。

          【讨论】:

          • 如果你不想乱扔文件,也可以使用 shell 函数myfunc() { command1 && command2}
          • 但是与在 .bashrc 文件中乱扔函数相比,“乱扔文件”没有那么混乱。考虑模块化:-)
          • shell 脚本是用什么语言编写的?
          • 信不信由你,您输入的 shell 不仅仅是“命令提示符”,而是一种完整的、图灵完备的编程语言(尽管语法很糟糕)。所以 shell 脚本是用 shell 的语言编写的。在 unixland 中有几种可用的 shell:sh(经典的 bourne shell)、bash(从 sh 演化而来的 bourne-again shell)、csh(经典的 c shell)、tcsh(从 csh 演化而来)、ksh(korn shell)......还有其他几个,但这些是最常见的。现在在 Linux 上,大多数使用 bash 编写 shell 脚本。
          • 请注意,没有必要以您在终端中使用的 shell 语言编写 shell 脚本,因为 shbang 行允许您指定脚本在哪个 shell 下运行。只需要在机器上安装用于编写脚本的 shell。
          【解决方案5】:

          为这些类型的东西定义函数可能比别名更容易,如果你想做的不仅仅是一个或两个命令,它会让事情更具可读性:

          在你的 .bashrc 中

          perform_my_command() {
              pushd /some_dir
              my_command "$@"
              popd
          }
          

          然后在命令行上你可以简单地做:

          perform_my_command my_parameter my_other_parameter "my quoted parameter"
          

          你可以在一个函数中做任何你喜欢的事情,调用其他函数等等。

          您可能想查看Advanced Bash Scripting Guide 以获得深入的知识。

          【讨论】:

            【解决方案6】:

            建议在一个别名中使用多个命令,您可以使用其中一个逻辑运算符来组合它们。这是一个切换到目录并对其执行 ls 的操作

                  alias x="cd /tmp && ls -al"
            

            另一种选择是使用 shell 函数。这些是 sh/zsh/bash 命令。我对其他 shell 的了解还不够,无法确定它们是否有效。

            至于 sudo 的事情,如果你想要它(虽然我认为这不是一个好主意),正确的做法是改变 /etc/sudoers 文件以获得你想要的东西。

            【讨论】:

              【解决方案7】:

              你可以使用这个别名:

              alias sequence='command1 -args; command2 -args;'
              

              或者如果第二个命令必须在第一个成功的情况下执行,则使用:

              alias sequence='command1 -args && command2 -args'
              

              【讨论】:

                【解决方案8】:

                要链接一系列命令,试试这个:

                alias x='command1;command2;command3;'
                

                或者你可以这样做:

                alias x='command1 && command2 && command3'
                

                && 使它只在前一个返回成功的情况下执行后续命令。

                对于交互式输入密码或与类似的其他程序交互,请查看 expect。 (http://expect.nist.gov/)

                【讨论】:

                • 我已经有一段时间没有这样做了,但我认为第一个建议将导致 3 个命令并行执行(或尽可能多),第二个将有 3 个串行执行的命令。无论哪种方式,我不确定他们是否会做同样的事情。
                • 我刚刚用 alias x='date;sleep 1;date' 试过了,输出是我所期望的(两个日期,相隔 1 秒),每个日期输出之间都有睡眠延迟。
                • @Frustrated:不。两者都是串行执行的。只有第一个不关心前一个命令是否失败。并行执行将是:command1 & command2 & command3
                • 知道如何使用通配符进行这项工作吗?比如说,我想在 git 上将我的本地 stage 分支签出到我的功能分支时删除它。
                • x 参数呢?
                猜你喜欢
                • 2018-05-10
                • 2010-10-19
                • 1970-01-01
                • 1970-01-01
                • 2015-06-17
                • 1970-01-01
                • 1970-01-01
                • 2016-08-15
                • 2010-10-11
                相关资源
                最近更新 更多