Bash

如何使 cd 命令在 bash 腳本子 shell 之外生效?

  • August 28, 2018

我做了這個腳本:

#!/bin/bash

if [[ $# -ne 1 ]]; then
 echo "only use one argument"
 exit 1
fi

mkdir $1
sleep 0.5
cd $1

exit 0

我想製作一個腳本,稍後將其放入 /usr/bin 中,這樣每當我編寫crdir asd它時,它就會創建目錄並自動將目前目錄更改為新目錄。

這種方式行不通,因為 schell 腳本顯然是一個子shell,而且 cd 命令在子shell之外不會生效,那我該怎麼做呢?

我在網上讀到我應該“獲取”它,在前面加一個點執行它,比如. ./crdir asd,但首先,當我嘗試這個時,ssh 與機器斷開連接,其次,這不會按我想要的方式工作它工作,作為一個命令。

有小費嗎?

編輯:我也嘗試過mkdir aaa; cd !#,但它沒有用,它!#作為上一個命令的參數。

讓它成為一個函式:

crdir() {
 if [ "$#" -eq 1 ]; then
   mkdir -p -- "$1" && cd -P -- "$1"
 else
   echo >&2 "Usage: crdir <directory-path>"
   return 1
 fi
}

你可以把它放在你的~/.bashrc.

您的. crdir方法也可以工作(在bash和其他.可以接受參數的 shell 中),但您需要刪除exit 0導致 shell 退出的那些。另請注意,當不在 POSIX 模式下時,bash如果在 中找不到該文件,則在目前目錄中查找要源文件,這使得它有點危險(與在末尾添加或空條目$PATH相同的級別) ..``$PATH

此外,如果. crdir不帶參數呼叫,則腳本將繼承 shell 的位置參數。例如,set foo; . crdir不會返回錯誤並會創建foo目錄。

關於腳本的其他一些註釋:

#!/bin/bash

請注意,當文件來源時,she-bang 被忽略(僅被視為註釋)。

if [[ $# -ne 1 ]]; then
  echo "only use one argument"

最好在 stderr ( echo >&2 text) 上輸出錯誤消息。

  exit 1
fi

mkdir $1

不加引號的參數擴展在 中具有特殊含義bash,您幾乎不應該這樣做。

此外,如果$1以 a 開頭-,它將被視為選項mkdir。您需要使用--選項結束標記來告訴mkdir內容$1不是選項,即使它以-.

您也沒有檢查mkdir命令是否成功。

您可能還想使用該-p選項告訴mkdir創建所有目錄組件,並且mkdir如果目錄已經存在,也會導致不返回失敗。所以:

mkdir -p -- "$1" &&
sleep 0.5

沒必要睡覺。mkdir返回成功可以確定目錄已經創建。

cd $1

同樣,你有引用和-問題。此外,bash您需要使用-Pcd其他實用程序(如mkdir. 所以:

cd -P -- "$1"

(暫時忽略一條名為-$CDPATH我希望您不要使用或僅與理智值一起使用的路徑)。

exit 0

同樣,您沒有檢查退出狀態cd並返回成功退出狀態,即使mkdircd失敗。當一個腳本被獲取時,它由源外殼解釋,所以這exit會導致它退出。

在這裡,我將腳本重寫為:

if [ "$#" -eq 1 ]; then
 mkdir -p -- "$1" && cd -P -- "$1"
else
 ! echo >&2 "Usage: crdir  <directory-path>"
fi

引用自:https://unix.stackexchange.com/questions/465318