Shell

shell變數測試擴展問題

  • December 21, 2017

我有這個程式碼:

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

任何人都可以幫忙嗎?

問題

問題是命令替換的結果會受到路徑名擴展和分詞的影響。

要查看命令替換的輸出會發生什麼,讓我們使用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"

好讀

關於從 shell 變數創建命令的問題的一個有趣且更普遍的討論是:“我試圖將命令放入變數中,但複雜的情況總是失敗!”

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