No terminal xfce4 eu executo:
if [[ $(pgrep -x xfce4-terminal) ]]; then echo "there are files" > test.txt; else echo "no files found" > test.txt; fi
que escreve there are files
em test.txt
. Se eu executar a mesma coisa em um script de shell, chamado enquanto o xfce4-terminal ainda estiver aberto, ele escreverá: no files found
no test.txt
:
if [[ $(pgrep -x xfce4-terminal) ]]; then echo "there are files" > test.txt; else echo "no files found" > test.txt; fi
Por que esse é o caso e o que eu tenho que fazer para corrigir (fazer o script de shells se comportar como o shell) isso?
Verificando$(pgrep -x xfce4-terminal)
Do Terminal:
echo $(pgrep -x xfce4-terminal) > toast.txt
# 8257
Do script de shell:
echo $(pgrep -x xfce4-terminal) > toast.txt
# 8257
A
[[ ... ]]
construção de teste estendida apareceu primeiroksh
e foi posteriormente copiada por outros shells, incluindobash
ezsh
.Se você tentar usá-lo em um shell POSIX simples
/bin/sh
(talvez porque você omitiu o shebang, por exemplo - consulte Qual interpretador de shell executa um script sem shebang? ) resultará em um erro de sintaxe - e isso fará com que umaif
condição falhe independentemente da veracidade do teste. Por exemplo:mas
No entanto ,
[[ $(pgrep -x xfce4-terminal) ]]
não é uma prática recomendada para testar se há um processo em execução chamadoxfce4-terminal
, mesmo quando o shell o suporta. Em vez de usar uma substituição de comando$(...)
para capturar a saída padrão dopgrep
comando e testar se é uma string não vazia, você pode usar o status de saídapgrep
diretamente. Deman pgrep
:Então
que funcionará em qualquer shell do tipo Bourne (sh, ksh, bash, zsh).
Na versão do terminal, você tem
[[ ]]
, que avalia seu conteúdo e retorna um status de saída 0 se o conteúdo for válido e 1 caso contrário. Se for passado apenas uma string, ele retornará 0 se a string tiver comprimento > 0 e 1 caso contrário. Como seu comando encontrou algo, ele retorna uma string com comprimento > 0 e[[ ]]
retorna um status de 0, ou 'true'.if
em scripts de shell usa o valor de retorno daif
instrução para determinar se deve ser executadothen
ouelse
. Se o valor de retorno for 0, ele executathen
, caso contrário, pula paraelse
.No entanto, se você marcar
man pgrep
, ele retornará o código de saída 1 para "um ou mais processos corresponderam aos critérios". Portanto,if
vê-lo como saindo com um código de erro diferente de zero e pula para o arquivoelse
.Para corrigir isso, basta colocar
[[ ]]
a versão do shell script também.