@geekosaurが説明したように、シェルはコマンドを実行する前にリダイレクトを実行します。これを入力すると:
sudo foo >/some/file
現在のシェルプロセスはそれ自体のコピーを作成し、最初/some/fileに書き込み用に開こうとし、次にそのファイル記述子を標準出力にしてから、を実行しsudoます。
許可されている場合(sudoer構成では、シェルの実行が妨げられることがよくあります)、次のようなことができます。
sudo bash -c 'foo >/some/file'
しかし、一般的に良い解決策は、の| sudo tee代わりに>との| sudo tee -a代わりに使用することです>>。そもそもリダイレクトが必要な唯一の理由である場合、これは特に便利ですsudo。結局のところ、rootとしてプロセスを不必要に実行することsudoは、避けるために作成されたものです。そしてecho、ルートとして実行するのはばかげています。
echo '[archlinuxfr]' | sudo tee -a /etc/pacman.conf >/dev/null
echo 'Server = http://repo.archlinux.fr/$arch' | sudo tee -a /etc/pacman.conf >/dev/null
echo ' ' | sudo tee -a /etc/pacman.conf >/dev/null
名前付きファイルと独自の標準出力の両方に出力を送信する> /dev/nullため、最後に追加しました。端末で表示する必要はありません。(コマンドは。それは、その名前を取得する場所である、物理的なパイプラインの「T」コネクタのように働く)そして、私は(単一引用符に切り替え... (代わりにdoubleの)...そのすべてがリテラルおよびIであるので) inの前にバックスラッシュを置く必要はありませんでした。(引用符または円記号がないと、シェルパラメーターの値に置き換えられます。これはおそらく存在しません。この場合、は何にも置き換えられず、消えてしまいます。)teetee''""$$arch$archarch$arch
つまり、sudo。を使用してrootとしてファイルに書き込むことができます。次に、シェルスクリプトで改行を含むテキストを出力する方法についての長い余談があります。:)
彼らが言うように、それをBLUFするために、私の好ましい解決策は、ヒアドキュメントを上記のsudo teeコマンドにフィードすることです。その場合、catorechoまたはprintforまたはその他のコマンドはまったく必要ありません。一重引用符はセンチネルの紹介に移動しました<<'EOF'が、同じ効果があります。本文はリテラルテキストとして扱われるため、その$archままにしておきます。
sudo tee -a /etc/pacman.conf >/dev/null <<'EOF'
[archlinuxfr]
Server = http://repo.archlinux.fr/$arch
EOF
しかし、それは私がそれを行う方法ですが、代替手段があります。ここにいくつかあります:
echo1行に1つずつ固定できますが、すべてをサブシェルにグループ化するため、ファイルに追加する必要があるのは1回だけです。
(echo '[archlinuxfr]'
echo 'Server = http://repo.archlinux.fr/$arch'
echo ' ') | sudo tee -a /etc/pacman.conf >/dev/null
(に追加-eし、echoその非POSIX拡張機能をサポートするシェルを使用している場合)\n:を使用して、文字列に改行を直接埋め込むことができます。
echo -e '[archlinuxfr]\nServer = http://repo.archlinux.fr/$arch\n ' |
sudo tee -a /etc/pacman.conf >/dev/null
しかし、上記のように、これはPOSIXで指定された動作ではありません。シェルは、代わり-eにリテラル\nの後にリテラルの束を含む文字列をエコーするだけかもしれません。これを行うPOSIXの方法はprintf、echo;の代わりに使用することです。引数は自動的に処理されecho -eますが、末尾に改行が自動的に追加されないため、\nそこに余分な行を追加する必要があります。
printf '[archlinuxfr]\nServer = http://repo.archlinux.fr/$arch\n \n' |
sudo tee -a /etc/pacman.conf >/dev/null
これらの解決策のいずれかを使用すると、コマンドが引数文字列として取得するものには2文字のシーケンスが含まれ、\nそれを改行に変換するのはコマンドプログラム自体(printfまたは内のコードecho)次第です。最近の多くのシェルでは、ANSI引用符$'...を使用するオプションがあります。これにより、コマンドプログラムが文字列を認識する前に、の'ようなシーケンス\nがリテラル改行に変換されます。つまり、このような文字列は、プレーン-eオールドレスを含むすべてのコマンドで機能しますecho。
echo $'[archlinuxfr]\nServer = http://repo.archlinux.fr/$arch\n ' |
sudo tee -a /etc/pacman.conf >/dev/null
ただし、echo -eANSI引用符はより移植性がありますが、それでもPOSIX以外の拡張機能です。
繰り返しになりますが、これらはすべてオプションですが、私はtee <<EOF上記のストレートソリューションを好みます。