今日、私はFTPごとにすべてのファイルを自分のターゲットサーバーにコピーする必要があるスクリプトを書いています。
スクリプトはzsh-shell内で実行されるので、正しく実行するには "sh script.sh"を使用する必要がありますか?
私も私のスクリプトをhttps://www.shellcheck.net/、大丈夫ですが、zsh-shellで次のエラーが発生します。
upload_file: command not found
#!/bin/bash
FTP_SERVER=ftp.ip
FTP_USER=ftp.user
FTP_PASS=ftp.passwd
FTP_DESTINATION_DIR="/destination_directory"
LOCAL_SOURCE_DIR="/home/$USER/pictures/local_pictures"
function upload_file {
local file=$1
echo "Hochladen von Datei $file"
ftp -inv "$FTP_SERVER" << EOF
user $FTP_USER $FTP_PASS
binary
cd $FTP_DESTINATION_DIR
put $file
quit
EOF
}
find "$LOCAL_SOURCE_DIR" \( -name "*.jpg" -o -name "*.png" \) -exec bash -c 'upload_file "$0"' {} \;
これらのスクリプトは慣れていません...
答え1
問題は、宣言した関数がbash
実行している2番目のインスタンスには表示されないことですfind ... -exec
。https://shellcheck.net/問題を見つけるのではなく、単一引用符で囲まれたリテラル文字列だけを見ることもできます。
Bashスクリプトの実行にsh
問題がある可能性があります。あなたのスクリプトは非標準宣言以外のBash機能を使用しませんが、function
実際には標準のPOSIX関数宣言構文よりもそれを好む理由はありません。 (sh
システムがBashへのシンボリックリンクである場合は、呼び出されたときに多くのBash専用機能がオフになっても機能する可能性がありますが、それでもsh
違いを理解し、それを使用してbash
Bashスクリプトを実行する必要があります。)
いずれにせよ、好ましいメカニズムはスクリプトを作成し、そのパスchmod +x
(またはディレクトリがユーザーのものである場合は名前のみ)を指定してPATH
実行することです。これを通してシェルボーン正しい通訳を選択してください。 (sh
またはを使用してスクリプトを明示的に実行した場合、bash
またはpython
など、完全に間違っている場合でもコメントとして無視されますcsh
。)
これらの詳細を修正した後、スクリプトは次のようになります。
#!/bin/bash
FTP_SERVER=ftp.ip
FTP_USER=ftp.user
FTP_PASS=ftp.passwd
FTP_DESTINATION_DIR="/destination_directory"
LOCAL_SOURCE_DIR="/home/$USER/pictures/local_pictures"
upload_file () {
local file=$1
echo "Hochladen von Datei $file"
ftp -inv "$FTP_SERVER" <<EOF
user $FTP_USER $FTP_PASS
binary
cd $FTP_DESTINATION_DIR
put $file
quit
EOF
}
export -f upload_file
find "$LOCAL_SOURCE_DIR" \( -name "*.jpg" -o -name "*.png" \) -exec bash -c 'upload_file "$0"' {} \;
より良い解決策は、upload_file
複数のファイル名を許可し、1つのFTPセッションのみを作成することです。
:
upload_file () {
( printf '%s\n' \
"user $FTP_USER $FTP_PASS" \
"binary" \
"cd $FTP_DESTINATION_DIR"
local file
for file; do
# print diagnostics to stderr
echo "Hochladen von Datei $file" >&2
echo "put $file"
done
echo "quit" ) |
ftp -inv "$FTP_SERVER"
}
export -f upload_file
find "$LOCAL_SOURCE_DIR" \( -name "*.jpg" -o -name "*.png" \) \
-exec bash -c 'upload_file "$@"' _ {} +
ところで、おそらく.sh
シェルスクリプトで拡張を使用しないでしょう。特に実際にスクリプトではない場合はさらにそうですsh
。これに対する厳格なルールはありませんが、ls
拡張もありません。なぜそうすべきですか?
答え2
ここで問題は、upload_file
この関数はスクリプト内でのみ使用できますbash
がfind
。
この問題を解決するには、次の手順を実行します。エクスポート機能これを使用してください:
typeset -fx upload_file
コマンドを呼び出す前に入れると、期待find
どおりに機能します。
編集:Tripleeeがコメントで指摘しました。export -f
も可能。これは間違いなくもっと読みやすいです。
答え3
関数を正しく宣言していないようです。出力と動作で見ると、欠けている括弧はfunction upload_file {...
次のようになりますfunction upload_file (){...
(質問を編集した後はこれが問題にならないと思います)。 Bashでは、
ステップで実行されたときに表示されるように関数をエクスポートする必要があります。bash -c
find
export -f upload_file
find "$LOCAL_SOURCE_DIR"...
あなたが見たように回答。