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/bash
como a primeira linha para definir o intérprete).
O sh
shell no Ubuntu énão bash
, mas um shell separado chamado dash
. dash
nã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 $UID
variá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 bash
com 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 sh
não pode ser assumido que defina essas variáveis. Em particular, sh
no Ubuntu é (atualmente, por padrão)dash
, o que não os define.
Você tem duas opções:
- Faça com que seu script seja executado em
bash
vez desh
. - 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 .sh
sufixo:
- Um
.sh
sufixo sugere que é compatível comsh
! - A maioria dos scripts não recebe nenhum sufixo, e ter um sufixo
.sh
ou.bash
pode 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 .sh
sufixo 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 defoo-bar/baz qux
, enquantospam\ ham
é a primeira palavra despam\ ham eggs
porque o espaço anteriorham
é escapado com uma barra invertida.cleanup
, se estiver em um diretório no seuPATH
(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 scriptcleanup
tem uma #!...
linha hashbang ou o que essa linha diz:
sh cleanup
ainda (tentará) executá-losh
como intérprete.bash cleanup
ainda (tentará) executá-lobash
como intérprete.
Isso ocorre porque, nesses casos, você está na verdade executando o interpretador ( sh
ou 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 sh
e bash
seguem 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 comocat
els
, é razoável esperar que esteja presente.
id
por si só gera um monte de informações, mas id -u
fornece 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. $UID
in bash
fornece o ID do usuário real e id -u
realmente corresponde ao bash
de $EUID
. Se você realmente deseja o UID e não o EUID, use id -ru
.