シェル変数テスト拡張の​​問題

シェル変数テスト拡張の​​問題

私はこのコードを持っています:

sed \
$( (( $compress == 1 )) && echo -n '-e /^RMTHOST/ s/$/, compress/' ) \
-e "s|\*\*jobname\*\*|$jobname|g" \
-e "s|\*\*hostname\*\*|$hostname|g" \
-e "s|\*\*hostport\*\*|$hostport|g" \
-e "s|\*\*rmttrailname\*\*|$rmttrailname|g" < $GGPARAMSDIR/pump.template > 
$GGPARAMSDIR/$jobname.prm

これは私が望むようにほぼ動作します。その場合は、文字列を含めたいと$compress == 1思います。この場合、この部分は含まれません。sed-e /^RMTHOST/ s/$/, compress/'$compress != 1

次のエラーが発生した場合$compress is 1

 sed: -e expression #1, char 10: missing command

デバッグ用にスクリプトに set -x を追加すると、次のように拡張されます。

sed -e '/^RMTHOST/' 's/$/,' compress/ -e 's|\*\*jobname\*\*|pssic|g' -e 's|\*\*hostname\*\*|omsssi|g' -e 's|\*\*hostport\*\*|7809|g' -e 's|\*\*rmttrailname\*\*|./dirdat/dsn/rc|g'

単一のティックが-e最初の式を閉じていることに注意してください/^RMTHOST/。これが私の問題を引き起こすと確信しています。ただし、問題を解決するための構文は不明です。

ちなみに変数の値はjobname=pssichostname=omsssihostport=7809

誰でも助けることができますか?

ベストアンサー1

質問

問題は、コマンド置換の結果がパス名拡張と単語分離の影響を受けることです。

コマンド置換の出力に何が起こるかを確認するために、それを使用して生成されたprintf単語を表示します。

$ printf ">%s<\n" $( (( compress == 1 )) && echo -n '-e /^RMTHOST/ s/$/, compress/' )
>-e<
>/^RMTHOST/<
>s/$/,<
>compress/<

本当に-e別の単語が必要です。ただし、単語を区切ると、sed置換コマンドがsedが実行するコマンドに分割される可能性があります。いいえ理解する:

$ sed -e '/^RMTHOST/' 's/$/,' 'compress/'
sed: -e expression #1, char 10: missing command

解決策

代わりにbash配列を試してください。

#!/bin/bash
jobname=pssic
hostname=omsssi
hostport=7809
compress=1
rmttrailname=SomethingElse

args=()
(( compress == 1 )) && args+=('-e' '/^RMTHOST/ s/$/, compress/')
args+=(
    -e "s|\*\*jobname\*\*|$jobname|g"
    -e "s|\*\*hostname\*\*|$hostname|g"
    -e "s|\*\*hostport\*\*|$hostport|g"
    -e "s|\*\*rmttrailname\*\*|$rmttrailname|g"
    )

declare -p args  # Optional: Verify the args are what we want.

sed "${args[@]}" <"$GGPARAMSDIR/pump.template" >"$GGPARAMSDIR/$jobname.prm"

よく読んだ

シェル変数からコマンドを生成する問題に関する興味深く、より一般的な議論は次のとおりです。「コマンドを変数に入れようとしていますが、複雑なケースは常に失敗します!」

おすすめ記事