1020

私は、開発中の RedHat Linux ボックスの 1 つで sudo アクセスを許可されており、通常は書き込みアクセスを持たない場所に出力をリダイレクトする必要があることがよくあるようです。

問題は、この不自然な例が機能しないことです。

sudo ls -hal /root/ > /root/test.out

私はただ応答を受け取ります:

-bash: /root/test.out: Permission denied

どうすればこれを機能させることができますか?

4

15 に答える 15

1415

に書き込む権限がないシェルによってリダイレクトが実行されるため、コマンドは機能しません/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。一時ファイルを作成したくない場合は、SteveBennettの回答を参照してください。

  • でシェルを起動して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
    

    ティーが画面に出力されないようにするには、へのリダイレクト/dev/nullが必要です。出力ファイル( )を上書きする代わりに追加するには、またはを使用します(最後のファイルはGNU coreutilsに固有です)。>>tee -atee --append

JdAdam J. ForsterJohnathanの2番目、3番目、4番目のソリューションに感謝します。

于 2008-09-17T11:48:56.063 に答える
128

ここの誰かが sudoing tee を提案しました:

sudo ls -hal /root/ | sudo tee /root/test.out > /dev/null

これは、アクセス権のないディレクトリにコマンドをリダイレクトするためにも使用できます。これは、tee プログラムが事実上「ファイルへのエコー」プログラムであり、/dev/null へのリダイレクトにより、画面への出力も停止して、上記の元の不自然な例と同じに保つために機能するためです。

于 2008-09-17T12:26:37.237 に答える
92

私が自分で見つけたトリックは

sudo ls -hal /root/ | sudo dd of=/root/test.out
于 2011-11-21T14:24:03.270 に答える
57

問題は、コマンドは の下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)

    # Read and append to a file
    cat ./'file1.txt' | sudo tee -a '/log/file.txt' > '/dev/null';
    
    # Store both stdout and stderr streams in a file
    { command1 arg; command2 arg; } |& sudo tee -a '/log/file.txt' > '/dev/null';
    
于 2008-09-23T10:10:04.167 に答える
25

ティーオプションが望ましい理由を少し明確にする

出力を作成するコマンドを実行するための適切な権限があると仮定すると、コマンドの出力を 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

これらの各例では、非特権コマンドの出力を取得し、通常はルートのみが書き込み可能なファイルに書き込みます。これが質問の起源です。

出力を生成するコマンドは昇格された権限で実行されないため、この方法をお勧めします。ここでは問題にならないように見えますechoが、source コマンドが完全に信頼できないスクリプトである場合、これは非常に重要です。

Note you can use the -a option to tee to append append (like >>) to the target file rather than overwrite it (like >).

于 2013-11-02T01:51:55.570 に答える
24

テーマのさらに別のバリエーション:

sudo bash <<EOF
ls -hal /root/ > /root/test.out
EOF

またはもちろん:

echo 'ls -hal /root/ > /root/test.out' | sudo bash

sudoまたはsh/への引数を覚える必要がないという (小さな) 利点があります。bash

于 2013-05-13T03:53:42.623 に答える
19

次のように、sudoにシェルを実行させます。

sudo sh -c "echo foo > ~root/out"
于 2008-09-17T11:48:32.307 に答える
14

私がこの問題に取り組む方法は次のとおりです。

ファイルの書き込み/置換が必要な場合:

echo "some text" | sudo tee /path/to/file

ファイルに追加する必要がある場合:

echo "some text" | sudo tee -a /path/to/file
于 2016-06-24T19:48:59.950 に答える
9

死んだ馬を打ち負かすつもりはありませんが、ここには を使用する回答が多すぎます。つまり、画面にコピーを表示したくない場合を除き、teeにリダイレクトする必要があります。stdout/dev/null

より簡単な解決策は、次のcatように使用することです。

sudo ls -hal /root/ | sudo bash -c "cat > /root/test.out"

リダイレクションが引用符で囲まれていることに注意してください。これにより、リダイレクションは、それを実行しているシェルではなく、によって開始されたシェルによって評価されsudoます。

于 2016-07-28T09:27:47.527 に答える
6

スクリプトを書いてみませんか?

ファイル名:myscript

#!/bin/sh

/bin/ls -lah /root > /root/test.out

# end script

次に、sudoを使用してスクリプトを実行します。

sudo ./myscript
于 2008-09-17T11:48:20.777 に答える
5

私はこのようにします:

sudo su -c 'ls -hal /root/ > /root/test.out'
于 2013-04-21T12:33:10.003 に答える
4

私がこのようなことをしなければならないときはいつでも、私はただルートになります:

# sudo -s
# ls -hal /root/ > /root/test.out
# exit

これはおそらく最善の方法ではありませんが、機能します。

于 2008-09-17T11:49:12.053 に答える
3

これは、 に関する回答に基づいています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 つで言及された懸念事項であった、デバイスへの書き込みに対する単純な保護も備えています。

于 2013-11-27T04:55:53.950 に答える
1

一部のプログラム/パスへの sudo アクセスのみが許可されている可能性がありますか? それからあなたが望むことをする方法はありません。(何らかの方法でハッキングしない限り)

そうでない場合は、bash スクリプトを記述できます。

cat > myscript.sh
#!/bin/sh
ls -hal /root/ > /root/test.out 

ctrl+を押すd:

chmod a+x myscript.sh
sudo myscript.sh

それが役立つことを願っています。

于 2008-09-17T12:00:45.163 に答える