修正する

修正する

FTPサーバーにログインし、いくつかのディレクトリの名前を変更するシェルスクリプトを作成しました。 FTPコマンドを次のような複数行の文字列に入れました。

# !/bin/sh

ftp -inv $HOST << EOF
user $USER $PASSWORD
$COMMANDS
bye
EOF

$COMMANDS改行で区切られたコマンドが含まれています。このアプローチは、次のコマンドを設定するときに機能します。

NL=$'\n'
COMMANDS="command one$NL"
COMMANDS+="command two$NL"
COMMANDS+="command three"

$COMMANDS最初は関数パディングを試しましたが、printf何度も試しても成功しませんでした。表現方式

COMMANDS="$(printf "%s\n" "command one" "command two" "command three")"

コマンド間にスペースがある文字列として評価され、スクリプトがFTPコマンドとして使用される場合は単一行として扱われます。

交換しようとしましたが、\n結果\rは変数$COMMANDSに文字列で埋められませんでした。

誰かがもっと教育を受けることができますか?お願いしますprintf説明してください。ここで機能に問題がありますか?

修正する

rsyncを使って目標を達成したので、FTP方式をあきらめましたが、なぜこれが起こるのかまだ疑問に思います。

問題はprintf変数に保存することです。テストスクリプトを作成しました。

echo "==== printf directly"
printf "%s\n" "foo" "bar" "baz"

echo "==== stored in variable"
VAR_1=$(printf "%s\n" "foo" "bar" "baz")
echo $VAR_1

./test.sh出力の実行

==== printf directly
foo
bar
baz
==== stored in variable
foo bar baz

設定はIFS=$'\n'役に立ちません。

アップデート2

変数を二重引用符で囲むと、変数から複数行を取得できます。

echo "$VAR_1"

しかし、heredocで使用すると、同じ結果は得られません。

echo `cat <<EOF
$VAR_1
"$VAR_1"
EOF`

私は出力を得る

foo bar baz "foo bar baz"

注:heredocの2つの変数出力の間には改行文字さえありません。これは私にとっても奇妙です。

答え1

引用符を使用しない場合、トークン化は文字列を空白(デフォルト)に分割し、分割されたecho部分を空白に関連付けます。実際、これは改行文字を「食べる」ことになります。

改善点を発見しました

echo "$VAR_1"

これで、この文書に対して同じことを行います。

echo "`cat <<EOF
$VAR_1
EOF`"

echo編集:食べる改行文字ではなく、殻です。

関連情報