使用 ’ 和 * 移動文件導致錯誤
我在 bash 腳本中移動文件時遇到問題。我一直在嘗試在同一問題上找到的不同解決方案,但找不到任何有效的解決方案。
我的最後一次嘗試是添加
shopt -s dotglob nullglob
,但這並沒有解決任何問題..在本次測試中,
jdir0="/media/sf_Mediaserver3/test22/abbamax.(6th.copy)..kansas.(1999)" mv -v "$jdir0/*" "$jdir0/subs/" &>> $debuglog
..我得到:
mv: cannot stat '/media/sf_Mediaserver3/test22/abbamax.(6th.copy)..kansas.(1999)/*': No such file or directory
但是,是的,有!
drwxrwx--- 1 root vboxsf 4096 Aug 22 07:06 ../ -rwxrwx--- 1 root vboxsf 0 Aug 21 17:19 'kallee.(222)..nnn.srt'* -rwxrwx--- 1 root vboxsf 159363 Aug 21 17:26 'movie.test(2929).ismim.mp4'* drwxrwx--- 1 root vboxsf 0 Aug 22 07:06 subs/
(名字真的很奇怪的原因是我在這個函式之前正在測試刪除無效字元)
更新:顯然我遇到了間歇性錯誤,幾天后我終於將其追溯到伺服器問題(儲存文件的位置)。顯然,如果伺服器沒有完成保存/名稱更改,並且腳本要求它做一些新的事情,就會發生這些錯誤。例如將文件A重命名為B,然後在伺服器執行第一個請求之前要求它將B重命名為C,導致伺服器說:B不存在,這當然會導致錯誤程式碼。
*
是 shell 的 glob 運算符。它需要不加引號才能被辨識。引用時,/media/sf_Mediaserver3/test22/abbamax.(6th.copy)..kansas.(1999)/*
按字面意思傳遞給mv
並mv
嘗試移動名為 的文件*
,但沒有這樣的文件。所以你需要:
mv -v -- "$jdir0"/* "$jdir0/subs/" >> "$debuglog" 2>&1
在
"$jdir0"/*
呼叫mv
.您不希望
nullglob
在這裡,因為這意味著在沒有與該"$jdir0"/*
模式匹配的文件的情況下,mv
將使用 just 呼叫-v
,--
並media/sf_Mediaserver3/test22/abbamax.(6th.copy)..kansas.(1999)/subs/
通過mv
.
failglob
在這種情況下,當 glob 不匹配時中止命令可能是一個更好的選擇,但請注意,bash
在這種情況下會以不一致的方式中止,具體取決於呼叫命令的上下文,這使得該選項在腳本中使用起來很棘手。
dotglob
是允許 glob 匹配隱藏文件。現在,請注意 glob 匹配文件,無論它們的類型是什麼¹,所以
*
上面也將匹配subs
. 如果subs
是一個目錄的符號連結,mv
會很樂意將該subs
符號連結移動到該目錄中,導致所有後續移動都失敗,因為subs
目標目錄現在已經消失了。如果subs
是一個普通的子目錄,mv
可能會抱怨它無法將目錄移動到自身中。所以你可能想寫它:
shopt -s extglob mv -v -- "$jdir0"/!(subs) "$jdir0/subs/" >> "$debuglog" 2>&1
!(pattern)
與任何不匹配的文件名匹配的 ksh 擴展 glob 運算符在哪裡pattern
,所以這裡移動任何文件,但subs
.另請注意,在
bash
shell 中,即使在非互動式 shell 實例中,在重定向目標中也需要引用參數擴展(bash 處於 POSIX 模式時除外)。¹ 除非您使用 zsh 而不是 bash 及其 glob 限定符,例如
*(.)
僅移動正常文件