使用bash运行多个命令而不生成子shell

时间:2018-05-17 14:17:26

标签: bash

cd folder &>/dev/null ||( mkdir folder && cd folder ) && git clone https://github.com/user/my-project.git

当运行上面的命令时,我遇到了问题(我认为),()生成一个子shell并运行命令,然后在运行git clone时我不在预期的目录中。有没有办法运行这条线?我目前的解决方案是

cd folder &>/dev/null || mkdir folder && cd folder && git clone https://github.com/user/my-project.git

问题是,即使目录存在,我也会运行cd folder两次

2 个答案:

答案 0 :(得分:3)

1。如何避免产生子shell

shell中有两个分组运算符:

  • ( commands… )在子shell中运行命令
  • { commands… }在当前执行环境中运行命令。

但请注意是shell 元字符,而 { } 不是。大括号是保留字,但前提是它们是完整的单词并且在命令中显示为第一个单词。因此,牙箍需要被空间包围,并且闭合支撑必须在分号后面。有关详细说明,请参阅bash command groups: Why do curly braces require a semicolon?

具体来说,你必须写

cd folder &>/dev/null || { mkdir folder && cd folder; } && git clone https://github.com/user/my-project.git

注意显式分号以终止管道。你也可以在subshel​​l复合命令中使用它,但是你必须使用它。

但是,您不应该真正使用此命令,因为如果在第一个folder失败之后和cd运行之前创建目录mkdir,则可能会失败。有一种更好的方法:

2。如何使这个命令更简单,更健壮

因为这确实是一项非常常见的任务,mkdir附带了有用的-p选项(Posix需要此选项)。

mkdir -p some/path

做了两件事:

  1. 如有必要,中间目录创建

  2. 如果最终目录已存在,则不会产生错误。

  3. 因此,像这样的任务的常见习语是:

    mkdir -p folder && cd folder && git clone https://github.com/user/my-project.git
    

    即使folder是完整路径并且需要添加路径上的多个目录,它也会起作用。

答案 1 :(得分:1)

()确实产生了一个子shell。以下是可能有用的单行命令示例:

if [ ! -d folder ]; then mkdir folder; fi; cd folder && git clone ...