Como McLovin diz , a variável UID
(e EUID
) readonly, definida automaticamente, é um recurso especial de bash
(e alguns outros shells). Não é padrão para shells estilo Bourne e sh
não pode ser assumido para definir essas variáveis. Em particular, sh
no Ubuntu é (atualmente, por padrão) dash
, que não os define.
Você tem duas opções:
- Faz com que seu script seja executado por
bash
em vez de sh
.
- Altere seu script para torná-lo mais portátil e não exija
bash
.
Executando seu script com bash
Você não nos disse o nome do seu roteiro (o que está bem). Vou chamá-lo cleanup
, pois esse é o nome do script semelhante no guia do qual você está trabalhando.
Note, em particular, que eu não estou chamando algo como cleanup.sh
. Isso é porque eu não recomendo que você nomeá-lo com um sufixo .sh
:
- Um sufixo
.sh
sugere que seja compatível com sh
!
- A maioria dos scripts não recebe um sufixo, e ter um sufixo
.sh
ou .bash
pode até ser interpretado como sugerindo que seu arquivo seja uma "biblioteca" em vez de um script de "nível superior". Ou seja, ele fornece código para ser originado por outros scripts (por exemplo, com o .
builtin) em vez de ser executado diretamente.
No entanto, incluir um sufixo .sh
não afetará o comportamento técnico de seu script de nenhuma maneira. Não há vantagem técnica ou desvantagem associada a isso.
Adicione uma linha de hashbang como a primeira linha do seu script: #!/bin/bash
Torne seu script executável com chmod +x cleanup
.
Agora você pode executar seu script executando o comando:
-
./cleanup
, quando estiver no diretório atual. (Especialmente quando o script para educação, exploração, teste, diversão ou outro uso limitado ou de uso único, esta é talvez a maneira mais comum.)
-
/path/to/cleanup
, em geral. Se a primeira palavra de um comando contiver um /
, ele será interpretado como caminho para um arquivo executável. (Essa é a razão para a sintaxe ./
acima, pois .
significa o diretório atual.)
Por primeira palavra , quero dizer o comando até, mas não incluindo, o primeiro espaço sem escape ou tab:
foo-bar/baz
é a primeira palavra de foo-bar/baz qux
, enquanto spam\ ham
é a primeira palavra de spam\ ham eggs
porque o espaço antes de ham
é escapado com uma barra invertida.
-
cleanup
, se estiver em um diretório no seu PATH
(e nenhum diretório listado tiver um executável com o mesmo nome e não for substituído por um construção do shell , função ou alias ).
Independentemente de o script cleanup
ter ou não uma linha #!...
hashbang ou o que a linha diz:
-
sh cleanup
continuará (tentando) executá-lo com sh
como o interpretador.
-
bash cleanup
continuará (tentando) executá-lo com bash
como o interpretador.
Isso ocorre porque, nesses casos, você está realmente 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 como sh
e bash
seguem essa convenção.
Tornando seu script portátil
Se você quiser tornar seu script portátil, a maneira mais simples é não usar $UID
, e em vez disso, usar algum recurso disponível para todos os shells ao estilo Bourne.
Em geral, não há recurso de shell interno para determinar o ID do usuário. Mas você pode usar id
. Este é um programa externo em vez de um shell embutido, mas como cat
e ls
, é razoável esperar que esteja presente.
id
em si gera muitas 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
corresponde a bash
' $EUID
'. Se você realmente quiser o UID e não o EUID, use id -ru
.