web-dev-qa-db-ja.com

1行のsudoでコマンド行を実行する

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

echo "something" > /path/foobar

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

私は試した

Sudo echo "something" > /path/foobar

sudoはeditのみをカウントし、適切な部分はカウントしないため、機能しません。
/>

確かに、Sudo suを使用する前にrootになるか、代わりにteeを使用できます。

echo "something" | Sudo tee /path/foobar

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

Sudo !!

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

21
rubo77

シェルコマンドの前にSudoを付けるだけではなく、シェルを呼び出してそのコマンドを再度評価する必要があります(変数の展開、リダイレクトオペレーターのファイルのオープンなどを行います)。だから〜だ

Sudo bash -c !!

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

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

または、現在実行中のbashと同じバージョンを確実に呼び出すには、次のようにします。

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

このコマンドは別のシェルプロセスで実行されるため、環境変数(Sudoが保持する変数のみ)を継承しますが、シェルの内部変数は継承しません。シェルオプション(例:kshglob)およびその他の設定は、デフォルトから開始されます。

同じコマンド²はzshとkshで機能しますが、ATT ksh93はfirstlastの両方の番号を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は、絶対パスである場合、またはスラッシュが含まれておらず、コマンド検索パスが変更されていない場合にのみ機能します。
³ fcはATT kshのhistのエイリアスですが、それでも同じです。

次のようなコマンドを実行した後、同じコマンドを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 !!
9
Boogy

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
deltab