理論

理論
#!/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を使用することをお勧めしますが、これは質問の範囲外です。ised

関連情報