@geekosaurが説明したように、シェルはコマンドを実行する前にリダイレクトを実行します。これを入力すると:
sudo foo >/some/file
現在のシェルプロセスは、最初に書き込み用に開こうとする自身のコピーを作成し/some/file
、それが成功すると、そのファイル記述子を標準出力にし、成功した場合にのみ実行しsudo
ます。これは最初のステップで失敗しています。
許可されている場合(sudoer構成ではシェルの実行が妨げられることがよくあります)、次のようなことができます。
sudo bash -c 'foo >/some/file'
しかし、一般的に良い解決策は、の代わりに、の代わりにを使用する| sudo tee
ことです。そもそもリダイレクトが必要な唯一の理由である場合、これは特に便利です。結局のところ、rootとしてプロセスを不必要に実行することは、避けるために作成されたものです。そして、rootとして実行するのはばかげています。>
| sudo tee -a
>>
sudo
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」コネクタのように機能し、その名前が付けられます。)そして、すべてがリテラルになるように、二重引用符( ... )ではなく一重引用符( ... )に切り替えました。 inの前にバックスラッシュを置く必要はありませんでした。(引用符または円記号がないと、シェルパラメーターの値に置き換えられます。これはおそらく存在しません。この場合、は何にも置き換えられず、消えてしまいます。)tee
tee
'
'
"
"
$
$arch
$arch
arch
$arch
つまり、。を使用してrootとしてファイルに書き込むことができますsudo
。次に、シェルスクリプトで改行を含むテキストを出力する方法についての長い余談があります。:)
彼らが言うように、それをBLUFするために、私の好ましい解決策は、ヒアドキュメントを上記のsudo tee
コマンドにフィードすることです。cat
その場合、 orecho
またはorprintf
またはその他のコマンドはまったく必要ありません。一重引用符は番兵の紹介に移動しました<<'EOF'
が、同じ効果があります。本文は文字通りのテキストとして扱われるため、その$arch
ままにしておきます。
sudo tee -a /etc/pacman.conf >/dev/null <<'EOF'
[archlinuxfr]
Server = http://repo.archlinux.fr/$arch
EOF
しかし、それは私がそれを行う方法ですが、代替手段があります。ここにいくつかあります:
1行に1つずつ固定できますがecho
、すべてをサブシェルにグループ化するため、ファイルに追加する必要があるのは1回だけです。
(echo '[archlinuxfr]'
echo 'Server = http://repo.archlinux.fr/$arch'
echo ' ') | sudo tee -a /etc/pacman.conf >/dev/null
に追加-e
する場合echo
(およびその非POSIX拡張機能をサポートするシェルを使用している場合)、次を使用して改行を文字列に直接埋め込むことができます\n
。
# NON-POSIX - NOT RECOMMENDED
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
ただし、ANSI引用符は、より移植性がecho -e
ありますが、それでも非POSIX拡張機能です。
繰り返しになりますが、これらはすべてオプションですが、私はtee <<EOF
上記のストレートソリューションを好みます。