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?

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.


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"

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"

@ 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


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”.


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"

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

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
}

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

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


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


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

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?


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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.