Bashスクリプトのコマンドを他のスクリプトのコマンドに置き換える

Bashスクリプトのコマンドを他のスクリプトのコマンドに置き換える

Mac OS Xで動作しないコマンドを含むスクリプトを含むgithubから変更を取得するスクリプトを設定しようとしています。
私の目標は、etcを使用してsedこのスクリプトのコマンドを置き換えることです。

次のコマンドは次のとおりです。

元のコマンド(スクリプトで置き換えられます):

DIR=$(dirname "$(readlink -f $0)")

新しいコマンド(置き換えたいコマンド):

DIR="$(cd "$(dirname "$0")" && pwd -P)"

私が今まで試したこと:

StartStopScript="/path/to/script.sh"

DIRnew=""$(cd "$(dirname "$0")" && pwd -P)""

DIRold=""$(dirname "$(readlink -f $0)")""

echo "$StartStopScript" | sed -e 's/"$DIRold"/"$DIRnew"/g'

これは失敗し、コマンドは文字列として解釈されずに実行されるようです。
図は引用符で帰結しますsed

私が受けることができる助けに感謝します。

ベストアンサー1

OrigScript="/path/to/script.sh"
echo $OrigScript
/path/to/script.sh
#note: no quotes
OrigScript='"/path/to/script.sh"'
echo $OrigScript
"/path/to/script.sh"
#note: with quotes, but not good for filesnames, rather use "$filename" in the command argument


DIRnew='"$(cd "$(dirname "$0")" \&\& pwd -P)"'
echo $DIRnew
"$(cd "$(dirname "$0")" \&\& pwd -P)"
#note: with quotes, escaping & needed for suppressing interpretation by sed

DIRold='"$(dirname "$(readlink -f $0)")"'
echo $DIRold
"$(dirname "$(readlink -f $0)")"
#note: in your question the original DIR=.. did NOT have double quotes,
#I assume a typo

sed -e "s/$DIRold/$DIRnew/g" "$OrigScript"
#note: $OrigScript should NOT have the double quotes in it!
#note: I assume $OrigScript == $StartStopScript

#test:
echo $DIRold | sed "s/$DIRold/$DIRnew/"
"$(cd "$(dirname "$0")" && pwd -P)"
#result includes double quotes!

1)(二重引用符)を使用して変数を宣言するには、引用符が文字列内に含まれるように引用符をエスケープする必要があります。これはまた、&使用を簡素化し、シェルが$()それを解釈しないため

2)echoing(二重引用符)の場合はエスケープしてください。

sed3)シェル変数を解釈するには、sedコマンドの周囲に二重引用符を使用する必要があります。一重引用符を使用すると、コマンドはsed 's/$a/$b/'実際の文字列 '$a'を文字列 '$b'に置き換えようとします。特殊ケース$)意味、任意の文字を含む文字列と同様に、sedコマンドの変数の周りにsed二重引用符は必要ありません(特殊コマンド文字に制限があります)。sedsed

4)echo "$StartStopScript" | sed -e 's/"$DIRold"/"$DIRnew"/g'変数をエコーし​​て$StartStopScript(これはスクリプトのファイル名だけであると仮定します)、その文字列の変数(ファイル名など)を変更しようとしています。sedファイルに適用するにはsed 's/a/b/g' file(output-write stout)を使用し、ファイルを上書きするには-i(注意して使用します。つまり、正しい置換を最初にテストします)

5)は、初期(一致)パターンを再印刷する&際に特別な意味を持ちます。sed

echo ABC | sed 's/A/&12/'
A12BC

解釈を抑制するには、代替パターンからエスケープする必要があります。

echo ABC | sed 's/A/\&12/'
&12BC

したがって、変数は$DIRnew文字列からバックスラッシュをエスケープする必要があります。

6) それに加えて、ループを使用してifオペレーティングシステムを識別し、それに応じてコマンドを調整することをお勧めします。これにより、両方のオペレーティングシステムに1つのスクリプトしか必要ありません。つまり

if [ OS = Mac ] ; then
    dir=MacDir
else
    dir=LinuxDir
fi

おすすめ記事