Scripting

擷取 SFTP 腳本中的錯誤

  • March 2, 2020

我有一個 sub sh 文件,它接收本地目錄的輸入和遠端目錄的路徑,並將文件發送到遠端目錄。如果遠端路徑無效,則無法檢測到錯誤。

sh 腳本中的範例內容:

sftp XXX@XXX.XXX.XXX.XXX <<==
cd $remote_dir                      <= error happens here
lcd $local_dir                      <= error did not happen so the return code resets
put a.tar
bye
==

$result=$?
return $result

有的應用程序呼叫sh文件,然後返回碼用來判斷文件是否發送成功。如果是,則將本地文件備份到某處,然後將其刪除。

問題是即使文件發送失敗,shell 也會返回零。該文件確實沒有被複製,您可以看到手動執行命令時發生錯誤,螢幕上顯示找不到路徑,但是當作為作業執行時,它會失敗。

我知道另一種方法是做兩步,首先檢查路徑是否存在,然後輸出到日誌文件並檢查日誌是否包含錯誤,如果沒有錯誤則可以呼叫 sftp put shell 腳本。我想知道是否還有其他方法。

在 SFTP 中處理錯誤很痛苦:SFTP 腳本語言沒有條件結構;要執行預定義的命令序列以外的任何操作,您需要在每個命令之後解析來自伺服器的輸出。您可以使用類似 的工具來做到這一點expect,但工作量很大,而且很難確保您已經涵蓋了所有情況。

對於您展示的範例,您可以使用

echo "put $local_dir/a.tar $remote_dir" | sftp XXX@XXX.XXX.XXX.XXX

但總的來說,錯誤處理很複雜。

所以不要使用SFTP。相反,使用SSHFS掛載遠端伺服器。這不需要在伺服器上進行任何特殊配置,因為 SSHFS 在後台使用 SFTP。您只需要讓FUSE在客戶端上工作。

SSHFS 將遠端文件的視圖顯示為本地電腦上已安裝的文件系統。因此,您可以使用諸如cdcp等普通命令來操作文件,而無需關心每個文件的位置(性能方面除外 - 例如,將文件從本地位置複製到遠端位置不會比您的上傳頻寬快)。

set -e
mkdir myserver
sshfs XXX@XXX.XXX.XXX.XXX/ myserver
cp -p "$local_dir/a.tar" "myserver/$remote_dir/"
…
fusermount -u

sftp使用以下-b選項執行:

sftp -b - XXX@XXX.XXX.XXX.XXX <<==
cd etc.
==

sftp手冊

-b batchfile

批處理模式從輸入批處理文件而不是標準輸入讀取一系列命令。由於它缺乏使用者互動,因此應與非互動身份驗證結合使用。’-’ 的批處理文件可用於指示標準輸入。如果以下任何命令失敗,sftp 將中止:get、put、reget、reput、rename、ln、rm、mkdir、 chdir、ls、lchdir、chmod、chown、chgrp、lpwd、df、symlink 和 lmkdir。可以通過在命令前加上“-”字元(例如,-rm /tmp/blah*)來逐個命令地抑制錯誤終止。

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