为什么在 bash 脚本中使用两个 cd 命令不执行第二个命令?

Jen*_*nny 15 bash scripts cd-command

我编写了一个 bash 脚本,它创建一系列目录并将项目克隆到选定的目录。

为此,我需要到cd每个目录(project 1project 2),但脚本不会cd到第二个目录,也不会执行命令。

相反,它会cdproject2目录中克隆后停止。为什么不调用cd_project1下面代码中的函数?

#!/bin/bash
#Get the current user name 

function my_user_name() {        
current_user=$USER
echo " Current user is $current_user"
}

#Creating useful directories

function create_useful_directories() {  
  if [[ ! -d "$scratch" ]]; then
  echo "creating relevant directory"
  mkdir -p /home/"$current_user"/Downloads/scratch/"$current_user"/project1/project2
  else
     echo "scratch directory already exists"
     :
  fi
}

#Going to project2 and cloning 

function cd_project2() {

  cd /home/"$current_user"/Downloads/scratch/"$current_user"/project1/project2 &&
  git clone https://username@bitbucket.org/teamsinspace/documentation-tests.git
  exec bash
}

#Going to project1 directory and cloning 
function cd_project1() {

  cd /home/"$current_user"/Downloads/scratch/"$current_user"/project1/ &&
  git clone https://username@bitbucket.org/teamsinspace/documentation-tests.git
  exec bash

}

#Running the functions  
function main() {

  my_user_name
  create_useful_directories
  cd_project2
  cd_project1    
}
main
Run Code Online (Sandbox Code Playgroud)

终端输出:

~/Downloads$. ./bash_install_script.sh    
Current user is mihi
creating relevant directory
Cloning into 'documentation-tests'...
remote: Counting objects: 125, done.
remote: Compressing objects: 100% (115/115), done.
remote: Total 125 (delta 59), reused 0 (delta 0)
Receiving objects: 100% (125/125), 33.61 KiB | 362.00 KiB/s, done.
Resolving deltas: 100% (59/59), done.
~/Downloads/scratch/mihi/project1/project2$
Run Code Online (Sandbox Code Playgroud)

Per*_*uck 28

罪魁祸首是您exec bash在某些函数中的语句。这exec句话有点奇怪,一开始不容易理解。这意味着:从这里开始执行以下命令而不是当前正在运行的命令/shell/脚本。那就是:它用一个实例替换当前的shell脚本(在你的情况下)bash并且它永远不会返回。

你可以用 shell 和 issue 试试这个

exec sleep 5
Run Code Online (Sandbox Code Playgroud)

这将用bash命令替换您当前的外壳程序 (the ),sleep 5 当该命令返回时(5 秒后)您的窗口将关闭,因为外壳程序已被替换为sleep 5.

同样的,你的脚本:如果你把exec something到你的脚本,该脚本被替换为something与当something停止执行时,整个脚本将停止。

简单地删除exec bash语句就可以了。

  • 顺便说一句,恭喜您在 cd 之后使用 && (如果您不使用 `set -e`)。我见过像 `cd tmp; 这样的代码。rm -rf *` 失败可怕 (9认同)
  • @Jenny 很高兴听到。轶事:Perl 语言也有一个具有相同行为的 `exec` 语句,如果你在一个 `exec` 语句之后放置一些语句(比如 `exec something; print "This won't run";`),那么 Perl 会警告你`print` 语句永远不会被执行。 (2认同)

ste*_*ver 15

来自help exec

exec: exec [-cl] [-a name] [command [arguments ...]] [redirection ...]
    Replace the shell with the given command.

    Execute COMMAND, replacing this shell with the specified program.
    ARGUMENTS become the arguments to COMMAND.  If COMMAND is not specified,
    any redirections take effect in the current shell.
Run Code Online (Sandbox Code Playgroud)

这里的关键词是替换——如果你exec bash从脚本内部,就不能再执行脚本了。