私は私たちの開発RedHat Linuxボックスの1つにSudoアクセス権を与えられました、そして私は私自身が通常は書き込みアクセス権を持っていない場所に出力をリダイレクトする必要があるようです。
問題は、この人為的な例は機能しないことです。
Sudo ls -hal /root/ > /root/test.out
私はただ応答を受けます:
-bash: /root/test.out: Permission denied
これを機能させるにはどうすればよいですか。
/root/test.out
への書き込み権限がないシェルによってリダイレクトが実行されるため、コマンドは機能しません。出力のリダイレクション はSudoによって実行された ではありません。
複数の解決策があります。
Sudoを使用してシェルを実行し、-c
オプションを使用してシェルにコマンドを渡します。
Sudo sh -c 'ls -hal /root/ > /root/test.out'
コマンドを使ってスクリプトを作成し、そのスクリプトをSudoで実行します。
#!/bin/sh
ls -hal /root/ > /root/test.out
Sudo ls.sh
を実行してください。一時ファイルを作成したくない場合は、Steve Bennettの answer を参照してください。
Sudo -s
を使用してシェルを起動してから、コマンドを実行します。
[nobody@so]$ Sudo -s
[root@so]# ls -hal /root/ > /root/test.out
[root@so]# ^D
[nobody@so]$
Sudo tee
を使用してください(-c
オプションを使用するときにたくさんエスケープする必要がある場合)。
Sudo ls -hal /root/ | Sudo tee /root/test.out > /dev/null
tee を画面に出力しないようにするには、/dev/null
へのリダイレクトが必要です。出力ファイル(>>
)を上書きする代わりにappendにするには、tee -a
またはtee --append
を使用します(最後のものは GNU coreutils に固有です)。
Jd 、 Adam J. Forster および Johnathan にアクセスして、2番目、3番目、4番目の解決策を見つけてください。
ここで誰かがTシャツをすくうことを提案したばかりです:
Sudo ls -hal /root/ | Sudo tee /root/test.out > /dev/null
これはまた、あなたがアクセスできないディレクトリに任意のコマンドをリダイレクトするのにも使用できます。これは、teeプログラムが事実上「ファイルへのエコー」プログラムであり、/ dev/nullへのリダイレクトが画面への出力も停止して上記の元の人為的な例と同じになるためです。
私が考え出したトリックは
Sudo ls -hal /root/ | Sudo dd of=/root/test.out
問題は、 コマンド はSudo
の下で実行されますが、 リダイレクト はユーザーの下で実行されるということです。これはシェルによって行われ、あなたがそれについてできることはほとんどありません。
Sudo command > /some/file.log
`-----v-----'`-------v-------'
command redirection
これを回避する通常の方法は以下のとおりです。
Sudoの下で呼び出すスクリプトにコマンドをラップします。
コマンドやログファイルが変更された場合は、スクリプトにこれらを引数として使用させることができます。例えば:
Sudo log_script command /log/file.txt
シェルを呼び出し、-c
を使用してコマンドラインをパラメータとして渡します。
これは、1回限りの複合コマンドには特に便利です。例えば:
Sudo bash -c "{ command1 arg; command2 arg; } > /log/file.txt"
テーマに関するさらに別のバリエーション:
Sudo bash <<EOF
ls -hal /root/ > /root/test.out
EOF
またはもちろん:
echo 'ls -hal /root/ > /root/test.out' | Sudo bash
Sudo
やsh
/bash
への引数を覚えておく必要がないという小さな利点があります。
teeオプションが望ましい理由を少し明確にします
出力を作成するコマンドを実行するための適切な権限があると仮定して、コマンドの出力をteeにパイプする場合は、teeの特権をSudoに昇格させて、teeに問題のファイルに書き込む(または追加する)だけで済みます。
質問の例では、次のようになります。
ls -hal /root/ | Sudo tee /root/test.out
より実用的な例をいくつか挙げます。
# kill off one source of annoying advertisements
echo 127.0.0.1 ad.doubleclick.net | Sudo tee -a /etc/hosts
# configure eth4 to come up on boot, set IP and netmask (centos 6.4)
echo -e "ONBOOT=\"YES\"\nIPADDR=10.42.84.168\nPREFIX=24" | Sudo tee -a /etc/sysconfig/network-scripts/ifcfg-eth4
これらの各例では、特権を持たないコマンドの出力を受け取り、通常はrootのみが書き込み可能なファイルに書き込みます。これが問題の原因です。
出力を生成するコマンドは昇格された特権で実行されないため、このようにすることをお勧めします。ここでecho
を使用しても問題ないようですが、sourceコマンドが完全に信頼できないスクリプトである場合、それは非常に重要です。
-aオプションを使用すると、ターゲットファイルを上書きするのではなく(>>
のように)append(>
のように)を追加することができます。
このように、Sudoにシェルを実行させます。
Sudo sh -c "echo foo > ~root/out"
私がこの問題について取り組む方法は次のとおりです。
あなたがファイルを書く/置き換える必要があるならば:
echo "some text" | Sudo tee /path/to/file
ファイルに追加する必要がある場合
echo "some text" | Sudo tee -a /path/to/file
スクリプトを書くのはどうですか?
ファイル名:myscript
#!/bin/sh
/bin/ls -lah /root > /root/test.out
# end script
次にSudoを使ってスクリプトを実行します。
Sudo ./myscript
私はこうします:
Sudo su -c 'ls -hal /root/ > /root/test.out'
このようなことをしなければならないときはいつでも、私はただrootになります。
# Sudo -s
# ls -hal /root/ > /root/test.out
# exit
これはおそらく最善の方法ではありませんが、うまくいきます。
死んだ馬を倒すつもりはありませんが、ここではtee
を使用する回答が多すぎます。つまり、画面上でコピーを見たいのでない限り、stdout
を/dev/null
にリダイレクトする必要があります。もっと簡単な解決策は、このようにcat
を使うことです:
Sudo ls -hal /root/ | Sudo bash -c "cat > /root/test.out"
リダイレクトが引用符で囲まれているため、実行中のシェルではなくSudo
で開始されたシェルによって評価されます。
これはtee
を含む答えに基づいています。物事を簡単にするために、私は小さなスクリプトを書いて(私はそれをsuwrite
と呼びます)そして/usr/local/bin/
パーミッションで+x
に入れます:
#! /bin/sh
if [ $# = 0 ] ; then
echo "USAGE: <command writing to stdout> | suwrite [-a] <output file 1> ..." >&2
exit 1
fi
for arg in "$@" ; do
if [ ${arg#/dev/} != ${arg} ] ; then
echo "Found dangerous argument ‘$arg’. Will exit."
exit 2
fi
done
Sudo tee "$@" > /dev/null
コードの _ usage _ に示されているように、必要なスーパーユーザーがアクセス可能なファイル名を続けて、このスクリプトに出力を渡すだけで済みます。 Sudo
を含みます。
echo test | suwrite /root/test.txt
これはtee
の単純なラッパーなので、追加するためにteeの-a
オプションも受け入れ、同時に複数のファイルへの書き込みもサポートします。
echo test2 | suwrite -a /root/test.txt
echo test-multi | suwrite /root/test-a.txt /root/test-b.txt
また、/dev/
デバイスへの書き込みに対する単純化された保護もあります。これは、このページのコメントの1つで言及されている問題です。
たぶんあなたはSudoにいくつかのプログラム/パスだけへのアクセスを与えられましたか?それならあなたが望むことをする方法はありません。 (あなたが何らかの形でそれをハックしない限り)
そうでない場合は、おそらくbashスクリプトを書くことができます。
cat > myscript.sh
#!/bin/sh
ls -hal /root/ > /root/test.out
押す ctrl + d :
chmod a+x myscript.sh
Sudo myscript.sh
お役に立てば幸いです。
Sudo at now
at> echo test > /tmp/test.out
at> <EOT>
job 1 at Thu Sep 21 10:49:00 2017