Debian
systemd and copy (/bin/cp): 沒有這樣的文件或目錄
在手動複製文件時,以下工作如下:
userx@x:~$ cp -rv /opt/test-bak/* /opt/test/ '/opt/test-bak/file1' -> '/opt/test/file1' '/opt/test-bak/file2' -> '/opt/test/file2' '/opt/test-bak/file3' -> '/opt/test/file3' '/opt/test-bak/subdir1/subfile1' -> '/opt/test/subdir1/subfile1' '/opt/test-bak/subdir2/subfile2' -> '/opt/test/subdir2/subfile2'
但是,將其安裝為系統服務會返回“cannot stat ‘/opt/test-bak/*’: No such file or directory”錯誤
● testcopy.service - test usage of /bin/cp in systemd Loaded: loaded (/etc/systemd/system/testcopy.service; disabled; vendor preset: enabled) Active: failed (Result: exit-code) since Sun 2019-04-21 14:55:16 +08; 4min 28s ago Process: 7872 ExecStart=/bin/cp -rv /opt/test-bak/* /opt/test/ (code=exited, status=1/FAILURE) Main PID: 7872 (code=exited, status=1/FAILURE) Apr 21 14:55:15 userx@x systemd[1]: Started test usage of /bin/cp in systemd. Apr 21 14:55:15 userx@x cp[7872]: /bin/cp: cannot stat '/opt/test-bak/*': No such file or directory Apr 21 14:55:16 userx@x systemd[1]: testcopy.service: Main process exited, code=exited, status=1/FAILURE Apr 21 14:55:16 userx@x systemd[1]: testcopy.service: Unit entered failed state. Apr 21 14:55:16 userx@x systemd[1]: testcopy.service: Failed with result 'exit-code'.
我的服務文件如下:
[Unit] Description=test usage of /bin/cp in systemd [Service] Type=simple ExecStart=/bin/cp -rv /opt/test-bak/* /opt/test/ [Install] WantedBy=multi-user.target
日誌顯示如下
Apr 21 15:05:12 x systemd[1]: Started test usage of /bin/cp in systemd. Apr 21 15:05:12 x cp[9892]: /bin/cp: cannot stat '/opt/test-bak/*': No such file or directory Apr 21 15:05:12 x systemd[1]: testcopy.service: Main process exited, code=exited, status=1/FAILURE Apr 21 15:05:12 x systemd[1]: testcopy.service: Unit entered failed state. Apr 21 15:05:12 x systemd[1]: testcopy.service: Failed with result 'exit-code'.
任何人都可以對此有所了解嗎?
在命令行上使用文件名通配模式時,外殼程序將通配模式擴展為與其匹配的文件名,創建一個路徑名列表,然後將其傳遞給您正在呼叫的實用程序(
cp
此處)。您在服務文件中指定的命令
ExecStart
不會在 shell 中執行。這意味著文件名通配模式*
不會被擴展,並且cp
將/opt/test-bak/*
作為要複製的單個文字源路徑呼叫。您可以嘗試將您的命令包裝在一個內聯的 shell 腳本中:
ExecStart=/bin/sh -c '/bin/cp -rv /opt/test-bak/* /opt/test/'
或者,將您的命令包裝在一個簡短的 shell 腳本中,
#!/bin/sh /bin/cp -rv /opt/test-bak/* /opt/test/
然後改為呼叫它。
由於我對 systemd 幾乎一無所知,但可能有更好的方法來做到這一點。
請注意,如果
*
glob 不匹配任何內容(因為目錄為空),那麼您將遇到與以前相同的問題。預設情況下,不匹配的 globbing 模式將保持未擴展。就個人而言,我會使用
cd /opt/test-bak && /bin/cp -Rp -v . /opt/test
或者
rsync -ai /opt/test/bak-test/ /opt/test
由於它們都不依賴 shell 生成文件名,因此它們都可以在沒有包裝 shell 的情況下執行。在這種情況下,不依賴 shell glob 也可以確保
bak-test
複製其中的隱藏文件和目錄。