#!/bin/bash
wineuser=tom
su $wineuser -c "sed -i '$ialias ptgui "wine ~/.wine/drive_c/Program\ Files/PTGui/PTGui.exe\"' /usr/people/$wineuser/config/cshrc.csh"
Tomのcshrc.cshに挿入された実際の行は次のようになります。
alias ptgui 'wine ~/.wine/drive_c/Program\ Files/PTGui/PTGui.exe'
sed コマンド '$ialias...' $i はファイルの最後の行の前に挿入され、定義された変数ではありません。
多段階脱出を説明するヒントやマニュアルも大歓迎です。
答え1
理論
ルールは次のとおりです。
'
区切り文字列内では何も解釈されず、a以外の他の内容は'
特別な意味がありません。これはエスケープだけが必要だという意味'
ですが、エスケープするには'\''
。 (最初の文字列は'
文字列を終了し、\'
リテラル'
(新しい文字列の開始を防ぐためにエスケープ処理)が続き、最後の文字列は'
新しい文字列を開始します。の連続した文字列として扱われます。文字列内で
"
変数拡張が発生し、エスケープが解釈されます。したがって、リテラルが必要な場合は\
エスケープする必要があります。また、リテラルが必要な場合は$
エスケープする必要があります(そうでない場合は変数拡張として解釈されます)。
必要に応じて、これら2つの引用スタイルを組み合わせて、さまざまな方法でコマンドをエスケープできます。以下のリストは、特定の問題に対する考えられる解決策の1つです。
sed
また、エスケープ文字としても解釈されることに注意してください\
。つまり、スクリプトで文字通り使用するときは、その文字をエスケープする必要があることを意味しますsed
。
はい
個人的には、私は最も内側のコード単位から始めて外側に作業する方が簡単だと思います。毎回、内部コード単位の外部参照メソッドで使用される特殊文字を参照します。
たとえば、ファイルの文字列を置き換えてIt's a test
結果をファイルに保存する場合は、次のように引用符を使用すると簡単になります。It's my test
/home/user/I have spaces in my name.txt
/home/user/NoSpaces.txt
"
sed "s/It's a test/It's my test/" "/home/user/I have spaces in my name.txt" >/home/user/NoSpaces.txt
これを変数に保存するには、別の参照レベルを追加する必要があります。
次の方法を使用してこれを実行できます(現在の文字列の他の文字を
'
エスケープすることを意味します)。'
myvar='sed "s/It'\''s a test/It'\''s my test/" "/home/user/I have spaces in my name.txt" >/home/user/NoSpaces.txt'
"
スタイル引用符を使用してこれを行うこともできます。myvar="sed \"s/It's a test/It's my test/\" \"/home/user/I have spaces in my name.txt\" >/home/user/NoSpaces.txt"
経験則は、常に最もクリーンであると考えられる解決策を選択することです。
離れた
特定の問題については、次のことを試すことができます。
cmd="sed -i '\$ialias ptgui '\\''wine ~/.wine/drive_c/Program\\\\ Files/PTGui/PTGui.exe'\\' /usr/people/$wineuser/config/cshrc.csh"
su "$wineuser" -c "$cmd"
nsertコマンドa
の代わりにpendを使用することをお勧めしますが、これは質問の範囲外です。i
sed