Como posso usar o sudo dentro de uma função?

3

Eu escrevi uma função que age de maneira semelhante a tee , mas também preenche um datestamp. tudo funciona bem, exceto quando eu quero dar saída para um arquivo que é apenas gravável por root (no meu caso, um arquivo de log dentro de /var/log ). Eu simplifiquei o seguinte trecho de código para incluir apenas os bits que não estão funcionando:

#!/bin/bash
#script ~/test_logger.sh
logfile=/var/log/test.log
logger()
{
    while read data
    do
        echo $data >> $logfile
    done
    return 0
}
sudo ls ~ | logger

funciona bem se eu executar o script inteiro como sudo ~/test_logger.sh , mas nem sempre posso fazer isso, pois quero usar a função de logger em arquivos como ~/.bash_logout , que são executados automaticamente. Eu tentei colocar sudo na frente do eco no loop while, mas isso não funciona. alguma idéia?

    
por mulllhausen 07.03.2011 / 06:39

5 respostas

9

geralmente é uma prática ruim colocar sudo em um script. A melhor escolha seria chamar o script com sudo de ~/.bash_logout ou onde quer que você queira usá-lo, se necessário, ou melhor ainda, tornar /var/log/test.log mundialmente gravável.

    
por 07.03.2011 / 07:19
7

como você descobriu, sudo command >out não funciona porque o 'comando' é executado pelo sudo, mas '> out' é uma função do shell, não do 'comando'. Então, você precisa escalar o próprio shell:

sudo sh -c "echo $data >>$logfile"

observe que você quer realmente ter certeza do que há em $ data fazendo isso:

~$ export data='good; touch /tmp/reallybad'
~$ echo $data
good; touch /tmp/reallybad
~$ sudo sh -c "echo $data>>/tmp/happy"
good
~$ ls /tmp/happy /tmp/reallybad
/tmp/happy  /tmp/reallybad

daí o aviso de simon.

    
por 07.03.2011 / 07:47
2

sudo não funciona da maneira que você pensa quando usa redirecionamento ou operadores de pipe. A alteração de fluxo não é executada com sudo de permissões. É por isso que

sudo echo foo >> bar

não funcionará se a barra for apenas gravável por raiz.

Quando você executa o script em sudo , tudo no script obtém permissões de superusuário para que funcione corretamente nessa circunstância.

Uma solução alternativa é fazer isso para garantir que o comando de gravação seja executado em sudo :

sudo echo foo | sudo tee bar > /dev/null

Lembre-se, no entanto, de que isso não é anexado ao arquivo. Sobrescreve o arquivo.

    
por 07.03.2011 / 06:48
1

Você está sudo usando apenas o comando ls , mas não logger . Bash não (e não deveria) saber o que o sudo faz, então apenas canaliza dois comandos. O primeiro é sudo e o segundo é logger . Não importa se você sudo ls , logger não.

Você deve sudo logger , mas não funcionará porque é uma função Bash em vez de um executável a ser executado por sudo .

BEWARE : ls | sudo logger invocará /usr/bin/logger se estiver instalado em seu sistema. Lembre-se: sudo não sabe sobre as funções do Bash.

Sugiro que você adicione o usuário invocando seu script ao grupo do proprietário do arquivo para que você possa escrever nele sem aumentar o privilégio especial.

Além disso, eficiência, você está abrindo e fechando o arquivo de log para cada linha lida. Você pode fazer isso apenas uma vez para todo o processo de registro:

function logger() {
  while read data
  do
    echo "$data"
  done
  return 0
} >>"$logfile"
    
por 09.12.2016 / 16:18
0

Bem, se você der uma olhada na página man do sudo você pode ver exemplos de como usá-lo nos scripts ... a opção -c permite executar um comando.

    
por 07.03.2011 / 08:54