當文件名作為變數傳遞時,ln -s 刪除文件名的一部分
我使用腳本將我下載的一些文件連結到不同的目錄。當文件名中有“-”時,ln -s 不會正確讀取路徑,即使該變數將正確記錄到我使用的日誌文件中。
for f in ${AVIFILES} do BaseAviName=$(basename "$f" .avi) aviMp4name="'""$targetdir""/""$BaseAviName"".mp4""'" linkAviFile="'""$targetdir""/""$f""'" downloadedFile=$("'""$theFile""/""$f""'") ln -s "$downloadedFile" "$linkAviFile" >>$logPath 2>&1 echo "fileIs: " "$f" ",linkAviFile is" "$linkAviFile" ",BaseAviName:" "$BaseAviName" '$aviMp4name: ' "$aviMp4name" '$downloadedFile: ' "$downloadedFile" >> "$logPath" done
這是來自的錯誤消息
ln
:ln: failed to create symbolic link ‘'/home/user/Videos/TVEpisodes/Parks and Recreation/Parks.and.Recreation.S03E01.DVDRip.XviD-REWARD.avi'’ -> ‘’: No such file or directory
即使使用正確的路徑記錄了變數下載的文件:
'/home/user/Downloads/Parks And Recreation - Season 3 - DVDRip-REWARD/Parks.and.Recreation.S03E01.DVDRip.XviD-REWARD.avi'
似乎,由於某種原因,當 $downloadedFile 被擴展以供 ln 使用時,ln 將省略部分文件名,從第一個“-”到下一個“/”(-第 3 季-DVDRip-REWARD” ). 我找不到發生這種情況的充分理由,並想避免它,任何建議……
編輯:我重寫了腳本,問題就消失了。感謝任何幫助過的人
即使使用正確的路徑記錄了變數下載的文件:
'/home/user/Downloads/Parks And Recreation - Season 3 - DVDRip-REWARD/Parks.and.Recreation.S03E01.DVDRip.XviD-REWARD.avi'
這顯然不是正確的路徑:它
'
在開頭和結尾都有額外的字元。您可以在以下錯誤消息中看到ln
:ln: failed to create symbolic link ‘'/home/user/Videos/TVEpisodes/Parks and Recreation/Parks.and.Recreation.S03E01.DVDRip.XviD-REWARD.avi'’ -> ‘’: No such file or directory
'
錯誤消息在“單引號”內包含文件名,並且開頭和結尾有額外的(ASCII 單引號)字元。腳本中的問題很明顯:
'
定義aviMp4name
,linkAviFile
和. 時添加了額外的字元downloadedFile
。不要那樣做。for f in "${AVIFILES[@]}" do BaseAviName=$(basename -- "$f" .avi) aviMp4name="$targetdir/$BaseAviName.mp4" linkAviFile="$targetdir/$f" downloadedFile=$("$theFile/$f") ln -s -- "$downloadedFile" "$linkAviFile" >>$logPath 2>&1 echo "fileIs: " "$f" ",linkAviFile is" "$linkAviFile" ",BaseAviName:" "$BaseAviName" '$aviMp4name: ' "$aviMp4name" '$downloadedFile: ' "$downloadedFile" >> "$logPath" done
在 shell源語法中,單引號分隔文字字元串,例如
a='hello world!'
將變數a
設置為 12 個字元的字元串hello world!
。如果將單引號放入變數中,則會返回單引號:a="'hello world!'"
設置a
為 14 個字元的字元串'hello world!'
。在 shell 腳本中使用引號要記住的關鍵是在變數擴展周圍加上雙引號,例如
ln -s -- "$downloadedFile" "$linkAviFile"
. 類似的程式碼ln -s -- $downloadedFile $linkAviFile
會拆分變數的值downloadedFile
和linkAviFile
空格字元,並將每個部分解釋為萬用字元模式。這些雙引號是 shell 源語法的一部分,它們由解析器解釋。將引號放入變數的值不會解決任何問題。另請注意,如果文件名以 a 開頭
-
,它將被命令解釋為選項。為避免這種情況,當變數中有文件名時,請--
在所有選項之後和所有文件名之前將參數傳遞給命令(--
如果您確定文件名不以 開頭-
,例如如果您知道它們,則可以省略’是絕對路徑)。--
意思是“在這一點之後沒有更多的選擇”。請注意
${AVIFILES}
,與任何其他未加引號的擴展一樣,它會在空格處拆分變數的值。要將多個文件名儲存在一個變數中,請將其設為數組而不是字元串;這需要 ksh、bash 或 zsh,它在普通 sh 中不起作用:AVIFILES=(foo.avi bar.avi "file name with spaces.avi")