更改到呼叫腳本的目錄的最安全(或最優雅或最短)的方法是什麼?
我想知道什麼可能是安全或與 Unix 兼容的方式來更改到呼叫腳本的目錄。
這兩種方法甚至可以在包含空格和特殊字元的目錄中使用,而無需使用引號。但在某些情況下,這可能不起作用。或者有嗎?
#!/bin/bash cd $(dirname $0) pwd cd ${0%/*} pwd ~/test 1"\ ü`\($$ ./cd.sh /home/syss/test 1"\ ü`\($ /home/syss/test 1"\ ü`\($
請注意,這
$0
可能是相對路徑,因此呼叫cd
兩次可能不起作用。除此之外,在大多數情況下,提取目錄部分的$0
工作。大多數不一樣*。*它可能失敗的一些情況包括:
- 腳本不是通過執行它的路徑來呼叫的,而是通過呼叫它的shell來呼叫的,例如
bash myscript
(它進行PATH
查找)。- 腳本在執行期間被移動。
只要您記錄必須在沒有惡作劇的情況下呼叫您的腳本,就可以使用目錄部分
$0
。你需要小心一點;如果它
$0
是通過一個空條目找到的,或者PATH
對於某些 shell,它是一個. 這個案例值得支持,也意味著你需要採取預防措施。PATH``.``${0%/*}
這種
dirname
方法也不是完全簡單的。命令替換在最後吃掉了換行符。對於這兩種方法,您需要注意字元串可以以選項開頭-
並被解釋為選項;傳遞--
終止命令的選項列表。case "$0" in */*) cd -- "${0%/*}";; *) cd -- "$0";; esac
或者
cd -- "$(dirname -- "$0"; echo /)"
關於雙引號,您問錯了問題。
"$0"
是參數的值0
。$0
,未加引號的,是參數的值,0
在每個元素的字元處拆分,IFS
然後解釋為全域模式,如果有任何匹配文件,則替換為匹配文件(只有在未關閉通配的情況下才會替換後一部分)。您並不是說參數的值0
在每個元素中的字元處拆分,IFS
然後解釋為全域模式並替換為匹配文件(如果有的話)(只有在沒有關閉全域的情況下),是嗎?你的意思是參數的值0
。所以寫下你的意思:"$0"
。您的測試沒有阻塞的唯一原因是您沒有嘗試使用有問題的名稱,並且您使用特定的外殼進行了測試,該外殼恰好可以在這種特定情況下修復您的錯誤。使用類似 的目錄名稱
foo bar
,您最終會傳遞兩個參數foo
和bar
給cd
命令;bash 的cd
命令將此解釋為“更改通過連接foo
、空格和獲得的目錄bar
”,因此它恰好重建了正確的名稱。不同的 shell 可能會將其解釋為“抱怨虛假參數”、“更改目錄”或“更改為在目前工作目錄中foo
通過替換獲得的foo
目錄”。bar
例如,使用 bash,如果名稱包含兩個連續的空格,您的腳本就會失敗。