Por que obtenho [[: não encontrado ao executar um script?

14

Estou tentando escrever um script que precisa verificar se existe um arquivo. No console eu escrevo

if [[ -a /path/to/file.txt ]]; then echo "not mod"; else echo "mod"; fi

e eu recebo

not mod

mas quando escrevo um script para fazer a mesma coisa:

#!/bin/sh
if [[ -a /path/to/file.txt ]]; then echo "not mod"; else echo "mod"; fi

e, em seguida, execute o script, recebo o seguinte:

./ex.sh: 2: [[: not found
mod

Salvei o script no diretório atual e o nomeei ex.sh, depois verifiquei que ele é executável. Para chamar o script, eu faço isso:

./ex.sh

Por que estou recebendo esse problema? Eu já tentei muitas coisas:

if [ -a /home ...

e

if test -a /home ...

Ambos retornam

13: -a: unexpected operator
Buzu
fonte
Consegui fazê-lo funcionar, mas para isso tive que remover a primeira linha (#! / Bin / sh) Você sabe por que isso acontece?
Buzu
tente#!/bin/bash
kev
olá kev, eu também relizei isso. Acabei de atualizar minha pergunta. Passei muito tempo nisso, mas estou feliz por poder resolvê-lo. Obrigado pela sua resposta. É, de fato, a solução para o problema.
Buzu
@Kev Por favor, poste isso como resposta
slhck 4/12/12
Buzu, @Kev - se você encontrar uma resposta, publique-a como resposta abaixo , não edite a pergunta.
precisa saber é o seguinte

Respostas:

9

Você está executando um script escrito para o bash sob sh , que não possui muitos dos recursos de sintaxe estendida - [[é um bashcomando interno e não está disponível no sh.

Mude #!/bin/shpara #!/bin/bashou para #!/usr/bin/env bash.

kev
fonte
Em alguns sistemas, /bin/shé um link simbólico para /bin/bash. E provavelmente é razoavelmente seguro supor que bashé /bin/bash.
perfil completo de Keith Thompson
@ Keith: É /bin/bashna maioria dos sistemas Linux, mas /usr/pkg/bin/bashem BSDs, ou /usr/local/bin/bashse um compilar diretamente da fonte.
user1686
@rawrawity: Ou em qualquer outro lugar que você decidir colocar se compilar a partir do código-fonte. Ok, bom ponto. Pessoalmente, prefiro editar o shebang para cada sistema do que usar o /usr/bin/envhack (que usa o que bashacontecer com os chamadores $PATHno momento), mas o YMMV. (E você pode fazer /bin/bashum link simbólico - se você tem direitos de administrador e você não se importa de brincar com /bin.)
Keith Thompson
@ Keith: /usr/localé onde o autotools decide colocá-lo por padrão. No que diz respeito "pessoalmente", eu gosto de ter vários servidores e VMs diferentes retirados do mesmo repositório de scripts / ferramentas, e não precisar reeditar os shebangs na metade deles após cada confirmação.
precisa saber é o seguinte
nenhum deles funcionou para mim: / im on centos
astroanu
0

Especifique bash em vez de sh ao executar o script. Eu pessoalmente notei que eles são diferentes no ubuntu 12.10:

bash script.sh arg0 ... argn

Smeterlink
fonte