1つのsudoを使用してコマンド行を実行する


21

たとえば、ファイルを作成し、1行にテキストを入力する場合、>演算子を使用して出力をファイルにリダイレクトできます。

echo "something" > /path/foobar

しかし、フォルダにアクセスできず、/path/sudo権限が必要な場合、sudo権限を持つ通常のユーザーと同じコマンドを実行するにはどうすればよいですか?

私は試した

sudo echo "something" > /path/foobar

しかし、それは機能しません。なぜなら、sudo editは、右の部分
ではなく、>

確かに、私は以前にrootになるsudo suか、tee代わりに使用することができました:

echo "something" | sudo tee /path/foobar

しかし、私は最後の行を置換として作業できる解決策を見つけたいと思います

sudo !!

最後の行を「リサイクル」sudoして前に追加する方法はありませんか?



これは重複ではありません。実際のQeustionを抽出し、タイトルを変更しました。今それは私が本当に探しているものです
rubo77

確か重複していました、現在は多少異なります。Boogyの答えに照らして質問を書き直したように思えますが、これは良いことです。それは良い答えです。投票は撤回しましたが、それでも避けられません(質問が問題に注意を払わずにキューに入れられると、人々はしばしば自動的に投票します):コメントが終了したら@goldilocksに対処し、再開するために投票します。それが起こったら、チャットであなたの主張を訴えることもできます。
goldilocks

回答:


13

sudoシェルコマンドの前にとどまることはできません。シェルを呼び出して、そのコマンドを再度評価する必要があります(変数の展開、リダイレクト演算子用のファイルのオープンなど)。だから〜だ

sudo bash -c !!

ただし!!、前のコマンドのテキスト、特殊文字、およびすべてを補間するため、これはまったく機能しません。コマンドのテキストを文字列として取得し、それを引数として渡す必要がありますsh。幸いなことに、bashのfc組み込み機能を使用すると、それを実行できます¹。

sudo bash -c "$(fc -ln -1)"

または、現在実行中のbashの同じバージョンを確実に呼び出すために:

sudo "$BASH" -c "$(fc -ln -1)"

コマンドは別のシェルプロセスで実行されるため、環境変数(sudo心を保持するもののみ)を継承しますが、シェル内部変数は継承しないことに注意してください。シェルオプション(kshglob)などの設定はデフォルトから開始されます。

ATTは、ksh93、両方の必要も同じcommand²は、zshのとkshので動作firstし、lastに渡す番号fc:³を(さらにはbash、zshの及びpdkshの/ mkshで動作します)

sudo zsh -c "$(fc -ln -1)"
sudo ksh -c "$(fc -ln -1 -1)"
sudo "$0" -c "$(fc -ln -1 -1)"

$0実行中のシェルの実行可能ファイルを指定するのに使用できるのは、シェルが$ PATHから呼び出され、$ PATHが変更されていない場合、または絶対パスから呼び出された場合のみです。

zshのもう1つの方法は、もう少し明確ですが、より長いものです。

sudo zsh -c $history[$[HISTCMD-1]]

警告の最後の言葉:sudo潜在的に危険なコマンド用です。使いやすくしすぎないでください!

¹ 冒頭に余分な空白があり、コマンド置換は末尾の改行を取り除きますが、シェルの構文はそれを気にしません。
² 私はzshのとは思わないかkshがbashののようなものを持っています$BASH$0絶対パスの場合、またはスラッシュが含まれておらず、コマンド検索パスが変更されていない場合にのみ機能します。
³ ATT kshのエイリアスですが、それでも同様です。 fchist


9

sudoで同じコマンドをやり直したい場合!! このようなコマンドを実行した後:

echo "something">/path/file

グローバル置換構文を使用してコマンドを呼び出します:

!!:gs/>/|sudo tee -a /

-aパラメーターの後にスペースを使用します。

これはsudoと同じです!! ただし、<および>のsudo制限を回避するのに役立ちます。sudoでは[<、>]を使用できないためです。


一般にリダイレクトのsudo制限をバイパスするには、次のように使用できます。

echo "something" | sudo tee myfile

teeコマンドを使用すると、標準入力から読み取り、標準出力およびファイルに書き込むことができます

コマンドを繰り返してテキストをファイルに追加する場合、teeコマンドには追加用の-aオプションがあります。だから、コマンドを思い出すことができます

sudo !!

テキストはファイルに追加されます

例:

echo "something" | sudo tee -a /path/file
sudo !!

いい解決策ですが、覚えるのが少し難しいです。!!を使用してコマンドのエイリアスを作成するにはどうすればよいですか最後のコマンドをリコールするには
rubo77

されて-a本当に必要?>ファイルを上書きし、tee -a追加します。これは>>
rubo77 14年

3

それは次のように単純なようsudo sh -c "!!"です:

$ cd /
$ echo hello > foo
bash: foo: Permission denied
$ sudo sh -c "!!"
sudo sh -c "echo hello > foo"
$ ls -l foo
-rw-r--r-- 1 root root 6 Jun 20 16:21 foo

3
コマンドが引用符を使用した場合、これは必ずしも同等ではありません。考えてみましょecho "foo bar"なると思われるsh -c "echo "foo bar""だけで印刷したfoo代わりにfoo bar
godlygeek 14年

私はsudo sh -c '!!'代わりにあなたのコマンドを試してみましたが、それでも動作しません
rubo77 14年

次に、コマンドで単一引用符と二重引用符の両方を使用した場合はどうなりますか?または二重引用符と変数展開?ユーザーが行った場合:a=b、その後echo "$a" >file、その後、sudo sh -c '!!'それがために拡大するsudo sh -c 'echo $a >file'のではなく、空の行を印刷しているbfile
godlygeek 14年

それで、おそらくもっと良い解決策がありますか?
rubo77 14年

1
コマンドを変更する必要なく、100%の時間で機能するソリューションはないと思います。を使用sudoしてルートシェルを取得し、その中にコマンドをコピーして貼り付けるのが最も近いですが、コマンドが非ルートシェルで設定された変数を使用すると予想される場合は失敗します。sudo sh -c "!!"単純なコマンドの使用はうまく機能しますが、複雑なコマンドの使用は困難です。最善のアドバイスは、100%動作するコマンドがあることを期待しないことです。いくつかの可能な解決策を学び、最適なときにそれぞれを適用します。
godlygeek 14年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.