web-dev-qa-db-ja.com

bashスクリプトで2つのcdコマンドを使用して2番目のコマンドを実行しないのはなぜですか?

一連のディレクトリを作成し、選択したディレクトリにプロジェクトを複製するbashスクリプトを作成しました。

そのため、各ディレクトリ(project 1project 2)にcdを付ける必要がありますが、スクリプトは2番目のディレクトリにcdせず、コマンドを実行しません。

代わりに、cdの後に停止し、project2ディレクトリに複製されます。次のコードで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://[email protected]/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://[email protected]/teamsinspace/documentation-tests.git
  exec bash

}

#Running the functions  
function main() {

  my_user_name
  create_useful_directories
  cd_project2
  cd_project1    
}
main

端末出力:

~/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$
15
Jenny

原因は、一部の関数のexec bashステートメントです。 execステートメントは少し奇妙で、そもそも簡単には理解できません。つまり、次のコマンドを実行します代わりに現在実行中のコマンド/シェル/スクリプトのここから。つまり:itは現在のシェルスクリプト(あなたの場合)をbashのインスタンスに置き換え、それは決して戻りません。

シェルと問題でこれを試すことができます

exec sleep 5

これにより、現在のシェル(bash)がコマンドsleep 5に置き換えられ、そのコマンドが(5秒後に)戻ると、シェルがsleep 5に置き換えられたため、ウィンドウが閉じます。

スクリプトと同じ:exec somethingをスクリプトに挿入すると、スクリプトはsomethingに置き換えられ、そのsomethingが実行を停止すると、スクリプト全体が停止します。

exec bashステートメントを削除するだけで十分です。

28
PerlDuck

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.

ここでのキーワードはreplaceです。スクリプト内からexec bashを実行すると、それ以上スクリプトが実行されなくなります。

15
steeldriver

開始したディレクトリに戻る場合は、次を使用できます

cd -

ただし、cdコマンドが実行されたかどうかが不明な場合は、作業ディレクトリをスタックに配置するためのコマンドを使用することをお勧めします。

pushd

そして、そこに戻ります(複数のディレクトリを変更した後でも)

popd

同等のpushdおよびpopdコマンドがあることを確認してください。

0