sudo echo „coś” >> / etc / privilegedFile nie działa

585

To dość proste pytanie, przynajmniej tak powinno być, dotyczące uprawnień sudo w Linuksie.

Istnieje wiele razy, kiedy tylko chcesz dołączyć coś /etc/hostslub plik podobny, ale w końcu nie jest w stanie, ponieważ oba >i >>nie są dozwolone, nawet z korzenia.

Czy istnieje jakiś sposób, aby tę pracę bez konieczności sulub sudo sudo korzeni?

David
źródło

Odpowiedzi:

854

Użyj tee --appendlub tee -a.

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

Pamiętaj, aby unikać cytatów w cudzysłowach.

Aby uniknąć drukowania danych z powrotem do konsoli, przekieruj dane wyjściowe do / dev / null.

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

Pamiętaj o flagi ( -a/ --append)! Po prostu teedziała jak >i nadpisze twój plik. tee -adziała jak >>i napisze na końcu pliku.

Yoo
źródło
3
Absolutnie wolę ten. To jest po prostu najprostsze (i myślałem o tee, co przydaje się również w innych scenariuszach).
Joachim Sauer
5
Zgadzam się. Wydaje się też, że jest fajniejszy niż rozpoczęcie nowego sh, zwłaszcza z potencjalnie robieniem rzeczy ze środowiskiem itp.
Sam Brightman,
39
Jedną ważną rzeczą do zapamiętania: NIGDY nie zapomnij o -a! Wyobraź sobie, co echo 'tmpfs /tmp tmpfs defaults 0 0' | sudo tee /etc/fstabbyś zrobił
mic_e
21
W systemie OS X powinno to być tee -azamiast tee --append.
knite
26
Dla tych, którzy nie rozumieją, co powiedział @mic_e: bez-a--append flagi ( ) polecenie zastąpiłoby cały plik danym ciągiem zamiast dołączać go na końcu.
totymedli
313

Problem polega na tym, że powłoka przekierowuje dane wyjściowe, a nie sudo lub echo, więc robi to zwykły użytkownik.

Wypróbuj następujący fragment kodu:

sudo sh -c "echo 'something' >> /etc/privilegedfile"
Matt P.
źródło
Jakie są „granice uprawnień sudo”? To właśnie powłoka, która przetwarza operatora przekierowaniu o wyższym priorytecie niż polecenia z oczywistych powodów
Vinko Vrsalovic
1
W zależności od twojego shecho może interpretować sekwencje specjalne, takie jak \twewnątrz pojedynczych cudzysłowów. Możesz printf %s 'something'zamiast tego użyć .
Lri
Korzystanie z tee jest bardziej popularne i kompatybilne z nowszymi dystrybucjami.
Eduardo B.,
1
Jest to jedyny taki, który działa jak-jest jako polecenie SSH, które można wykonać na zdalnym węźle.
Duncan Lock
Zgadzam się z innymi postami tutaj. Używa powłoki i tylko powłoki, więc nie jest wymagany inny program, taki jak tee. Tak, wiem, że tee jest już zainstalowany, ale może nie zależy to od tego, jakiej mikro dystrybucji używasz jak alpejskie gołe kości. Podoba mi się, że masz również opcję powłoki: sudo /bin/bash -c "echo 'fs.inotify.max_user_watches = 524288' > /etc/sysctl.d/60-golang-inotify.conf"na przykład.
Ligemer
35

Problem polega na tym, że to twoja powłoka obsługuje przekierowanie; próbuje otworzyć plik z twoimi uprawnieniami, a nie z procesem uruchomionym w sudo.

Użyj czegoś takiego, na przykład:

sudo sh -c "echo 'something' >> /etc/privilegedFile"
Incydent
źródło
@ GordonSun dzieje się tak, ponieważ sudo(ze względów bezpieczeństwa) nie propaguje środowiska do podprocesu. Możesz użyć, sudo -Eaby ominąć to ograniczenie.
arielf
1
@ GordonSun tak to zrobię, nie rozumiem, dlaczego ciągle powtarzasz to oświadczenie! Jeśli tak sudo sh -c "echo 'something' >> $FILENAME", z podwójnym cudzysłowie, to będzie działać - zmienna podstawienie odbywa się przez powłokę zewnętrzną, a nie sudoed powłoki.
Nadav Har'El
19
sudo sh -c "echo 127.0.0.1 localhost >> /etc/hosts"
Vinko Vrsalovic
źródło
13

Robić

sudo sh -c "echo >> somefile"

powinno działać. Problem polega na tym, że> i >> są obsługiwane przez twoją powłokę, a nie przez polecenie „sudoed”, więc uprawnienia są twoje, a nie uprawnienia użytkownika, do którego „sudoing”.

agnul
źródło
9

Dla ciekawskich chciałbym zauważyć, że możesz również zacytować heredoc (dla dużych bloków):

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"
msanford
źródło
1
Działa to świetnie, z tym że osadzone cytaty mogą wymagać ucieczki \
N Jones
Zupełnie dobrze @NJones! Zmienię swoją odpowiedź. (Należy jednak pamiętać, że nie wykonanie tego "powoduje usunięcie wewnętrznej, ale nie powoduje niepowodzenia polecenia.)
msanford
8

W bash możesz używać teew połączeniu z, > /dev/nullaby utrzymać stdout w czystości.

 echo "# comment" |  sudo tee -a /etc/hosts > /dev/null
Vytenis Bivainis
źródło
4

Korzystając z odpowiedzi Yoo , umieść to w ~/.bashrc:

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

Teraz możesz biegać sudoe 'deb blah # blah' /etc/apt/sources.list


Edytować:

Bardziej kompletna wersja, która umożliwia wprowadzanie danych do pliku lub przekierowywanie z niego i zawiera -aprzełącznik do wyłączania dołączania (który jest domyślnie włączony):

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
}
hololeap
źródło
2

Możesz także użyć spongez moreutilspakietu i nie trzeba przekierowywać wyjścia (tzn. Nie ma teehałasu do ukrycia):

echo 'Add this line' | sudo sponge -a privfile
Michael Goldshteyn
źródło
0

Używając sed -i z $ a , możesz dodać tekst, zawierający zarówno zmienne, jak i znaki specjalne, po ostatnim wierszu.

Na przykład dodanie $ NEW_HOST z $ NEW_IP do / etc / hosts:

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

wyjaśniono opcje sed:

  • -i w miejscu
  • $ za ostatnią linię
  • dla append
Noam Manos
źródło
0

echo „Hello World” | (sudo tee -a /etc/apt/sources.list)

Sudev Shetty
źródło
0

Co powiesz na:
echo text | sudo dd status = none of =
plik uprzywilejowany Chcę zmienić / proc / sys / net / ipv4 / tcp_rmem.
Zrobiłem:
sudo dd status = none of = / proc / sys / net / ipv4 / tcp_rmem <<< "4096 131072 1024000"
eliminuje echo w dokumencie zawierającym jeden wiersz

Marcelo Pacheco
źródło
1
Poświęć chwilę, aby przeczytać pomoc dotyczącą edycji w Centrum pomocy . Formatowanie w przypadku przepełnienia stosu jest inne niż w innych witrynach.
Dharman
-1

To działało dla mnie: oryginalne polecenie

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

Dowództwo robocze

echo "export CATALINA_HOME="/opt/tomcat9"" |sudo tee /etc/environment
Fthi.a.Abadi
źródło
1
Powinno być tee -a. Po prostu teenadpisze plik!
codeforester
-6

Czy możesz zmienić własność pliku, a następnie zmienić go z powrotem po użyciu cat >>do dołączenia?

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

Coś takiego działa dla ciebie?

pixistix
źródło
4
Chown to destrukcyjne polecenie, którego należy użyć. Jeśli menedżer konfiguracji użył tego do aktualizacji / etc / hosts, nagle / etc / hosts należy do użytkownika config, a nie root. co potencjalnie prowadzi do tego, że inne procesy nie mają dostępu do / etc / hosts. Celem sudo jest uniknięcie konieczności zalogowania się do katalogu głównego i poprzez sudoers można nałożyć także więcej ograniczeń.
David