パイプラインの途中で特権を昇格するにはどうすればよいですか?


8

私の推測は次のとおりです:

echo "Generating some text" | su - -c cat >/output/file

しかしsu言う:

su: must be run from a terminal

あなたならどうしますか?


自分で解決策を見つけた場合は、以下の回答として追加してください。
Braiam 2014

@Braiamソリューションは答えに値するものではありません。
x-yuri 2014

回答:


8

sudo これをサポートします。

$ echo hello world | sudo cat  
SUDO password: 
hello world

違いsudoは、root(ターゲットユーザー)パスワードではなく、ユーザーパスワードを要求することです。ただし、必要に応じて、のtargetpw(またはrunaspwor rootpw)ディレクティブを使用してこの動作を変更できますsudoers.conf


ただし、これはアクセス許可のエスカレーションの問題を解決しますが、意図したことを実行することはできません。意味/output/filerootユーザーとして作成されません、それはあなたのユーザーとして変更/作成されます。

この理由は、コマンドを呼び出す前にシェル出力リダイレクトが行われるためです。そのため、シェルが開いて/output/file、開いたファイルをsu/ sudo(そしてその結果cat)に渡します。

ただしteeteeユーティリティを使用してファイル自体を開くため、これを代わりに使用してこれを行うことができます。

echo "hello world" | sudo tee /output/file >/dev/null

基本的にtee、出力を/output/fileとSTDOUTにコピーしますが、STDOUTはにリダイレクトされ/dev/nullます。

あなたも行うことができます:

echo "hello world" | sudo sh -c 'cat > /output/file'

...それほど不可解ではありません。


を呼び出して、昇格された権限を「キャッシュ」することもできsudo -vます。sudoを数分使用しなかった場合は、パスワードを要求されます。
Winny

2

ちょうどあなたが知っている-あなたは1つのコマンドに制限されていません|pipe

this happens | then this | { then ; all of ; this too ; } | before this

これらのプロセスはすべて同時に呼び出されますが、|pipe実際に何かを実行する前に|pipe、すべてを読み取るまで、つまり、すべてのプロセスが実行される前に待機します。したがって、変数の途中で評価する必要がある場合、またはリダイレクトを設定する必要がある場合は、そうすることができます。時間をかけてください。

echo "it takes time" |
{ exec 4>|file ; cat >&4 ; } |
( sleep 1 && cat <file )

it takes time

ここに別の方法があります:

echo "more of the same" |
( IFS= ; su -mc 'echo '"$(printf "'%s' " "`cat`")"' >|file' </dev/tty ) |
echo end of pipe

そうしないと( subshell )、コマンド$(cat)も取得さ</dev/ttyれます。

ただし、ヒアドキュメントを使用している場合は、2つcatのは必要ありません。

rm ./file
su -c 'cat <&3 >|./file; echo "middle here"' 3<<HERE >&2 | {\
    until [ -s ./file ] ; do sleep 1 ; done ;\
    sed 's/beginning/end/' ./file ; }
$(echo "this is the beginning" | sed 'a\of the pipeline' | tee /dev/stderr)
HERE

出力:

this is the beginning
of the pipeline
Password:
middle here
this is the end
of the pipeline

上記のほとんどは、これをデモするためのものです。本当に必要なのは:

su -c 'cat <&3 >./file' 3<<HERE | { wait as needed ; more stuff to do ; }
$(echo "something" | and other things)
HERE

そんなこと知ってる。それは質問とはほとんどまたはまったく関係がないと思います。しかし、どういうわけかそれは私に答えを導きました:)私の更新された質問を参照してください。
x-yuri 2014

@ x-yuriヒアドキュメントをパイプラインの途中に置くこともできます。何かをエコー| {su '何かをする> /record.here'; } << HERE | パイプのエコー終了\ n $(cat)\ nHERE \ n
mikeserv

確かに、私はここのドキュメントの中で猫を使うことを考えていませんでした。とにかく、そこでグループ化する必要はありません。
x-yuri 2014

@ x-yuri-それは何をしたいかによります。どちらかまたは両方を使用できます。私はあなたに選択肢があることを証明しようとしただけでした。パトリックの答えはここで正しいものです。これは単なる別の、より複雑な方法です。ただし、ヒアドキュメントはグループ化しますが、サブシェルで猫をグループ化します。
mikeserv 2014

グループ化とは、中括弧を意味しまし
x-yuri 2014
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.