sudo を使用して、書き込み権限のない場所に出力をリダイレクトするにはどうすればよいですか?

StackOverflow https://stackoverflow.com/questions/82256

質問

私は開発用 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. 。スティーブ・ベネットの作品を参照 答え 一時ファイルを作成したくない場合。

  • でシェルを起動します 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 止めるために必要です ティー 画面への出力から。に 追加する 出力ファイルを上書きする代わりに(>>)、 使用 tee -a または tee --append (最後のものは、 GNU コアユーティリティ).

ありがとう ジェーディー, アダム J.フォースター そして ジョナサン 2 番目、3 番目、4 番目のソリューションの場合。

他のヒント

ここの誰かが sudoing 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

T 字型オプションが好ましい理由を少し明確にする

出力を作成するコマンドを実行するための適切な権限があると仮定すると、コマンドの出力を tee にパイプする場合、必要なのは sudo を使用して tee の権限を昇格し、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 ただし、ソース コマンドが完全に信頼できないスクリプトである場合、これは非常に重要です。

-a オプションを使用して tee を追加することができることに注意してください。 >>) を上書きするのではなく、ターゲット ファイルにコピーします (例: >).

次のように、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

脚本を書いてみてはどうでしょうか?

ファイル名:私のスクリプト

#!/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

に示すように、 使用法 コード内で行う必要があるのは、出力をこのスクリプトにパイプし、その後にスーパーユーザーがアクセスできる目的のファイル名を指定することだけです。必要に応じて、パスワードの入力を自動的に求めるプロンプトが表示されます (パスワードには次のものが含まれるため) sudo).

echo test | suwrite /root/test.txt

これは単純なラッパーであるため、 tee, 、Tシャツも受け付けます -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  
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top