O que há de errado com este script?

O que há de errado com este script?

Então peguei este script deste guia: www.tldp.org/LDP/abs/abs-guide.pdf

LOG_DIR=/var/log
ROOT_UID=0
LINES=50
E_XCD=86
E_NOTROOT=87

if [ "$UID" != "$ROOT_UID" ]
then
echo "Must be root to run this script."
exit $E_NOTROOT
fi

if [ -n "$1" ]
then
lines=$1
else
lines=$LINES
fi

cd $LOG_DIR

if [ 'pwd' != "$LOG_DIR" ]
then
echo "Can't change to $LOG_DIR."
exit $E_XCD
fi

Agora eu fiz sudo su no terminal e ecoei $UID, o que me dá 0. Isso significa que minha condição if acabou sendo falsa, mas ainda estou recebendo "Deve ser root para executar este script". ao executar este script.

Também no script original esta condição if foi dada como

if [ "$UID" -ne "$ROOT_UID" ]

mas eu estava recebendo um erro de número ilegal porque aparentemente -ne é usado apenas para string, então mudei para!

Responder1

Em vez de executá-lo com

sh script.sh

execute-o com

bash script.sh

(ou adicione #!/bin/bashcomo a primeira linha para definir o intérprete).

O shshell no Ubuntu énão bash, mas um shell separado chamado dash. dashnão possui tantos recursos quanto o bash, o que o torna mais eficiente, mas esses recursos ausentes às vezes quebram os scripts destinados ao bash. Uma dessas características é a $UIDvariável, que énão definidoem dash.

Isso significa que quando o script for executado dash, a comparação se tornará ["" != "0"], que é avaliada como verdadeira, independentemente do usuário que o estiver executando. No entanto, se for executado bashcom permissões de root, as strings serão iguais e o script funcionará.

Responder2

ComoMcLovin dizUID, a variável somente leitura (e ) definida automaticamente EUIDé um recurso especial debash(e algumas outras conchas). Não é padrão paraConchas estilo Bournee shnão pode ser assumido que defina essas variáveis. Em particular, shno Ubuntu é (atualmente, por padrão)dash, o que não os define.

Você tem duas opções:

  1. Faça com que seu script seja executado em bashvez de sh.
  2. Mude seu script para que seja mais portátil e não exija bash.

Executando seu script combash

Você não nos disse o nome do seu script (o que está certo). vou ligarcleanup, pois esse é o nome do script semelhante no guia em que você está trabalhando.

Observe em particular que estounãochamando-o de algo como cleanup.sh. Isso ocorre porque não recomendo que você nomeie-o com um .shsufixo:

  • Um .shsufixo sugere que é compatível com sh!
  • A maioria dos scripts não recebe nenhum sufixo, e ter um sufixo .shou .bashpode até ser interpretado como uma sugestão de que seu arquivo é uma "biblioteca" em vez de um script de "nível superior". Ou seja, ele fornece código a ser originado por outros scripts (por exemplo, com o .integrado) em vez de realmente ser executado diretamente.

No entanto, incluir um .shsufixo não afetará de forma alguma o comportamento técnico do seu script. Não há vantagem ou desvantagem técnica associada a isso.

Adicione umlinha hashbangcomo a primeira linha do seu script:#!/bin/bash

Torne seu script executávelcom .chmod +x cleanup

Agora você podeexecute seu scriptexecutando o comando:

  • ./cleanup, quando estiver no diretório atual. (Especialmente ao criar scripts para educação, exploração, teste, diversão ou outro uso limitado ou único, esta é talvez a forma mais comum.)

  • /path/to/cleanup, em geral. Se a primeira palavra de um comando contiver um, /ela será interpretada como o caminho para um arquivo executável. (Essa é a razão da ./sintaxe acima, pois .significa o diretório atual.)

    Porprimeira palavraQuero dizer, o comando até, mas não incluindo, seu primeirosem escapeespaço ou tabulação:
    foo-bar/bazé a primeira palavra de foo-bar/baz qux, enquanto spam\ hamé a primeira palavra de spam\ ham eggsporque o espaço anterior hamé escapado com uma barra invertida.

  • cleanup, se estiver em um diretório no seu PATH(e nenhum diretório listado primeiro tiver um executável com o mesmo nome e não for substituído por umshell embutido,função, ouapelido).

Independentemente de ser ou não um scriptcleanuptem uma #!...linha hashbang ou o que essa linha diz:

  • sh cleanupainda (tentará) executá-lo shcomo intérprete.
  • bash cleanupainda (tentará) executá-lo bashcomo intérprete.

Isso ocorre porque, nesses casos, você está na verdade executando o interpretador ( shou bash) e passando o nome do script para o interpretador, para ser executado. Muitos programas aceitam nomes de arquivos para abrir na linha de comando e shells gostam she bashseguem esta convenção.

Tornando seu script portátil

Se você quiser tornar seu script portátil, a maneira mais simples é não usá $UID-lo e, em vez disso, usar algum recurso disponível para todos os shells do estilo Bourne.

Em geral, não há nenhum recurso de shell integrado para determinar o ID do usuário. Mas você pode usarid. Este é um programa externo em vez de um shell embutido, mas comocatels, é razoável esperar que esteja presente.

idpor si só gera um monte de informações, mas id -ufornece apenas o ID do usuário efetivo.

Então, em vez de if [ "$UID" != "$ROOT_UID" ], você pode usar:

if [ "$(id -u)" != "$ROOT_UID" ]

Tecnicamente, isso não é equivalente. $UIDin bashfornece o ID do usuário real e id -urealmente corresponde ao bashde $EUID. Se você realmente deseja o UID e não o EUID, use id -ru.

informação relacionada