sudo echo“ something” >> / etc / privilegedFileが機能しない


586

これは非常に単純な質問です。少なくともLinuxのsudo権限については、そうあるべきだと思われます。

私はちょうどに何か追加したい時に多くの時間があります/etc/hostsか、類似したファイルを両方のためにできることではない終わる>>>さえルートで、許可されていません。

root を使わずに、suまたはsudo surootに入れずにこの作業を行う方法はありますか?

回答:


855

tee --appendまたはを使用しtee -aます。

echo 'deb blah ... blah' | sudo tee -a /etc/apt/sources.list

引用符内の引用符は避けてください。

データをコンソールに出力しないようにするには、出力を/ dev / nullにリダイレクトします。

echo 'deb blah ... blah' | sudo tee -a /etc/apt/sources.list > /dev/null

-a/ --append)フラグについて覚えておいてください!のteeように機能し>、ファイルを上書きします。tee -aのように機能し>>、ファイルの最後に書き込みます。


3
私はこれを絶対に好む。これは最も単純なものです(他のシナリオでも役立つTシャツについて学びました)。
ヨアヒムザウアー

5
同意する。新しいshを開始するよりもすっきりしているようです。特に、環境などで何かをする可能性がある場合
Sam Brightman

39
注意すべき重要な点の1つ:-aを忘れないでください!a echo 'tmpfs /tmp tmpfs defaults 0 0' | sudo tee /etc/fstabが何をするか想像してみてください
mic_e

21
OS Xでは、これはのtee -a代わりになりtee --appendます。
2015

26
:@mic_eが言ったことを理解していない人のためにすることなく、-a--append)フラグコマンドはファイル全体上書きしてしまい最後にそれを追加するのではなく、与えられた文字列とを。
totymedli 2015年

314

問題は、シェルがsudoやechoではなく出力リダイレクトを行うことです。そのため、これは通常のユーザーとして行われています。

次のコードスニペットを試してください。

sudo sh -c "echo 'something' >> /etc/privilegedfile"

「sudo許可境界」とは何ですか?明白な理由で、コマンドよりも優先順位が高いリダイレクト演算子を解析するのはシェルにすぎません
Vinko Vrsalovic

1
に応じてsh、echoは\t単一引用符内のようなエスケープシーケンスを解釈できます。printf %s 'something'代わりに使用できます。
Lri

Teeの使用はより人気があり、新しいディストリビューションとの互換性が高くなっています。
Eduardo B.

1
これは、リモートノードで実行できるSSHコマンドとしてそのまま機能する唯一のものです。
ダンカンロック

私はここの他の投稿に同意します。これはシェルと唯一のシェルを使用するため、ここではteeのような別のプログラムは必要ありません。はい、ティーがすでにインストールされていることはわかっていますが、使用しているマイクロディストリビューションによっては、骨のない高山のようなものではない場合があります。シェルオプションもあるといいですねsudo /bin/bash -c "echo 'fs.inotify.max_user_watches = 524288' > /etc/sysctl.d/60-golang-inotify.conf"。たとえば。
Ligemer

35

問題は、リダイレクトを処理するのがシェルであることです。sudoで実行しているプロセスのアクセス許可ではなく、ユーザーのアクセス許可でファイルを開こうとしています。

このようなものを使用してください:

sudo sh -c "echo 'something' >> /etc/privilegedFile"

@GordonSunこれはsudo(セキュリティ上の理由から)環境がサブプロセスに伝播されないためです。sudo -Eこの制限を回避するために使用できます。
arielf 2018年

1
@GordonSunはいそうです、なぜあなたはこの声明を繰り返し続けるのか分かりません!その場合はsudo sh -c "echo 'something' >> $FILENAME"、二重引用符で、これがします仕事-変数置換は、外殻、ないsudoedシェルによって行われます。
Nadav Har'El


13

している

sudo sh -c "echo >> somefile"

うまくいくはずです。問題は、>と>>が「sudoed」コマンドではなくシェルによって処理されるため、権限は「sudoed」するユーザーの権限ではなく、ユーザーの権限です。


9

好奇心旺盛な方のために、ヒアドキュメントを引用することもできます(大きなブロックの場合)。

sudo bash -c "cat <<EOIPFW >> /etc/ipfw.conf
<?xml version=\"1.0\" encoding=\"UTF-8\"?>

<plist version=\"1.0\">
  <dict>
    <key>Label</key>
    <string>com.company.ipfw</string>
    <key>Program</key>
    <string>/sbin/ipfw</string>
    <key>ProgramArguments</key>
    <array>
      <string>/sbin/ipfw</string>
      <string>-q</string>
      <string>/etc/ipfw.conf</string>
    </array>
    <key>RunAtLoad</key>
    <true></true>
  </dict>
</plist>
EOIPFW"

1
これは、埋め込まれた引用符を除いて、素晴らしい作品\でエスケープする必要があるかもしれません
N・ジョーンズ

@NJones!回答を編集します。(ただし、これを"行わないと内部が
取り除かれ

8

bashではtee、と組み合わせて使用し> /dev/nullて、標準出力をクリーンに保つことができます。

 echo "# comment" |  sudo tee -a /etc/hosts > /dev/null

4

ユの答えを使って、これをあなたの中に入れてください~/.bashrc

sudoe() {
    [[ "$#" -ne 2 ]] && echo "Usage: sudoe <text> <file>" && return 1
    echo "$1" | sudo tee --append "$2" > /dev/null
}

これで実行できます sudoe 'deb blah # blah' /etc/apt/sources.list


編集:

パイプ入力またはファイルからのリダイレクトを可能にし、-a追加をオフにするスイッチを含むより完全なバージョン(デフォルトではオンになっています):

sudoe() {
  if ([[ "$1" == "-a" ]] || [[ "$1" == "--no-append" ]]); then
    shift &>/dev/null || local failed=1
  else
    local append="--append"
  fi

  while [[ $failed -ne 1 ]]; do
    if [[ -t 0 ]]; then
      text="$1"; shift &>/dev/null || break
    else
      text="$(cat <&0)"
    fi

    [[ -z "$1" ]] && break
    echo "$text" | sudo tee $append "$1" >/dev/null; return $?
  done

  echo "Usage: $0 [-a|--no-append] [text] <file>"; return 1
}

2

パッケージspongeから使用することもできmoreutils、出力をリダイレクトする必要はありません(つまり、tee非表示にするノイズがありません)。

echo 'Add this line' | sudo sponge -a privfile

0

sed -iを使用$ a、最後の行の後に、変数と特殊文字の両方を含むテキストを追加できます。

たとえば、$ NEW_IPを含む$ NEW_HOSTを/ etc / hostsに追加します。

sudo sed -i "\$ a $NEW_IP\t\t$NEW_HOST.domain.local\t$NEW_HOST" /etc/hosts

sedオプションの説明:

  • -iインプレース
  • 最終行の $
  • APPEND用


0

方法:
エコーテキスト| sudo dd status = none of = privilegedfile
/ proc / sys / net / ipv4 / tcp_rmemを変更したい。
私がしました:
sudo dd status = none of = / proc / sys / net / ipv4 / tcp_rmem <<< "4096 131072 1024000"
は、1行のドキュメントでエコーを排除します


1
一読する瞬間を取ってください編集のヘルプ、ヘルプセンター。Stack Overflowでのフォーマットは他のサイトとは異なります。
ダーマン

-1

これは私のために働きました:オリジナルのコマンド

echo "export CATALINA_HOME="/opt/tomcat9"" >> /etc/environment

作業コマンド

echo "export CATALINA_HOME="/opt/tomcat9"" |sudo tee /etc/environment

1
する必要がありますtee -a。ただ、teeファイルが上書きされます!
codeforester

-6

ファイルの所有権を変更してからcat >>、追加に使用した後で元に戻すことはできますか?

sudo chown youruser /etc/hosts  
sudo cat /downloaded/hostsadditions >> /etc/hosts  
sudo chown root /etc/hosts  

このような何かがあなたのために働きますか?


4
Chownは破壊的なコマンドです。構成マネージャーが/ etc / hostsを更新するためにそれを使用した場合、突然/ etc / hostsはrootではなく構成ユーザーに属します。他のプロセスが/ etc / hostsにアクセスできない可能性があります。sudoの要点は、何かがrootにログインすることを回避することであり、sudoersを介してより多くの制限を同様に積み重ねることができます。
デビッド
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.