sudo echo “qualcosa” >> / etc / privilegedFile non funziona


586

Questa è una domanda piuttosto semplice, almeno sembra che dovrebbe essere, sui permessi sudo in Linux.

Ci sono molte volte in cui voglio solo aggiungere qualcosa /etc/hostso un file simile, ma alla fine non riesco perché entrambi >e >>non sono ammessi, anche con root.

Esiste un modo per far funzionare tutto questo senza il bisogno suo il sudo suroot?

Risposte:


855

Usa tee --appendo tee -a.

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

Assicurati di evitare virgolette tra virgolette.

Per evitare di stampare nuovamente i dati sulla console, reindirizzare l'output su / dev / null.

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

Ricorda la bandiera ( -a/ --append)! Proprio teefunziona come >e sovrascrive il file. tee -afunziona come >>e scriverà alla fine del file.


3
Preferisco assolutamente questo. È solo il più semplice (e mi ha fatto riflettere sul tee, che è utile anche in altri scenari).
Joachim Sauer,

5
Sono d'accordo. Sembra più ordinato di iniziare anche un nuovo sh, specialmente con potenzialmente fare cose con l'ambiente ecc.
Sam Brightman,

39
Una cosa importante da notare: MAI dimenticare il -a! Immagina cosa echo 'tmpfs /tmp tmpfs defaults 0 0' | sudo tee /etc/fstabfarebbe
mic_e il

21
In OS X, questo dovrebbe essere tee -ainvece di tee --append.
Knite

26
Per coloro che non capiscono cosa ha detto @mic_e: senza il-a--append flag ( ) il comando sovrascriverebbe l'intero file con la stringa data invece di aggiungerlo alla fine.
totymedli,

314

Il problema è che la shell emette il reindirizzamento, non sudo o echo, quindi questo viene fatto come utente normale.

Prova il seguente frammento di codice:

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

Cosa sono i "limiti di autorizzazione sudo"? È solo la shell che analizza l'operatore di reindirizzamento con una precedenza superiore rispetto a un comando per ovvie ragioni
Vinko Vrsalovic,

1
A seconda del tuo sh, l'eco può interpretare sequenze di escape come \tall'interno di virgolette singole. printf %s 'something'Invece potresti usare .
Lri,

L'uso di tee è più popolare e più compatibile con le nuove distribuzioni.
Eduardo B.

1
Questo è l'unico che funziona così com'è come un comando SSH che può essere eseguito su un nodo remoto.
Duncan Lock,

Sono d'accordo con altri post qui. Questo utilizza una shell e solo una shell, quindi qui non è richiesto un altro programma come tee. Sì, lo so che Tee è già installato, ma forse non dipende da quale micro distro stai usando come ossa nude alpine. Mi piace che tu abbia anche un'opzione shell: sudo /bin/bash -c "echo 'fs.inotify.max_user_watches = 524288' > /etc/sysctl.d/60-golang-inotify.conf"ad esempio.
Ligemer,

35

Il problema è che è la shell che gestisce il reindirizzamento; sta provando ad aprire il file con le tue autorizzazioni non quelle del processo che stai eseguendo su sudo.

Usa qualcosa del genere, forse:

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

@GordonSun questo perché sudo(per motivi di sicurezza) non propaga l'ambiente al sottoprocesso. È possibile utilizzare sudo -Eper ignorare questa limitazione.
arielf

1
@GordonSun sì, non capisco perché continui a ripetere questa affermazione! Se lo fai sudo sh -c "echo 'something' >> $FILENAME", con doppi apici, questo sarà lavorare - la sostituzione di variabile è fatto il guscio esterno, non la shell sudoed.
Nadav Har'El


13

fare

sudo sh -c "echo >> somefile"

dovrebbe funzionare. Il problema è che> e >> sono gestiti dalla shell, non dal comando "sudoed", quindi le autorizzazioni sono le tue, non quelle dell'utente su cui stai "eseguendo la sudo".


9

Vorrei notare, per i curiosi, che puoi anche citare un heredoc (per blocchi di grandi dimensioni):

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
Funziona benissimo, tranne per il fatto che potrebbe essere necessario sfuggire alle citazioni incorporate con un \
N Jones il

Abbastanza giusto @NJones! Modificherò la mia risposta. (Notare, tuttavia, che non farlo spoglia l'interno "ma non causa il fallimento del comando.)
msanford,

8

In bash puoi usarlo teein combinazione con > /dev/nullper mantenere pulito lo stdout.

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

4

Usando la risposta di Yoo , inseriscilo nel tuo ~/.bashrc:

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

Adesso puoi correre sudoe 'deb blah # blah' /etc/apt/sources.list


Modificare:

Una versione più completa che consente di reindirizzare l'input o il reindirizzamento da un file e include un -ainterruttore per disattivare l'aggiunta (che è attivata per impostazione predefinita):

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

È inoltre possibile utilizzare spongedal moreutilspacchetto e non è necessario reindirizzare l'output (ovvero, nessun teerumore da nascondere):

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

0

Usando sed -i con $ a , puoi aggiungere del testo, contenente sia variabili che caratteri speciali, dopo l'ultima riga.

Ad esempio, aggiungendo $ NEW_HOST con $ NEW_IP a / etc / hosts:

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

spiegazione delle opzioni sed:

  • -i per sul posto
  • $ per l'ultima riga
  • a per append


0

Che ne dici di:
testo eco | sudo dd status = nessuno di = file privilegiato
Voglio cambiare / proc / sys / net / ipv4 / tcp_rmem.
Ho fatto:
sudo dd status = nessuno di = / proc / sys / net / ipv4 / tcp_rmem <<< "4096 131072 1024000"
elimina l'eco con un documento a riga singola


1
Ti preghiamo di dedicare un momento alla lettura della guida alla modifica nel Centro assistenza . La formattazione su Stack Overflow è diversa rispetto ad altri siti.
Dharman,

-1

Questo ha funzionato per me: comando originale

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

Comando di lavoro

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

1
Dovrebbe essere tee -a. Basta teesovrascrivere il file!
codeforester,

-6

Puoi cambiare la proprietà del file e poi cambiarlo dopo averlo usato cat >>per aggiungere?

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

Qualcosa del genere funziona per te?


4
Chown è un comando distruttivo da usare. Se un gestore di configurazione lo utilizzava per aggiornare / etc / hosts, improvvisamente / etc / hosts appartiene all'utente della configurazione e non al root. che potenzialmente porta ad altri processi che non hanno accesso a / etc / hosts. Il punto centrale di sudo è quello di evitare di avere qualcosa collegato a root e tramite sudoer si possono accumulare anche altre restrizioni.
David,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.