Expansão do parâmetro parece estar faltando uma peça

2

Atualmente, estou aprendendo a escrever scripts simples e não consigo entender um problema muito simples.

Eu tenho o seguinte comando no meu script ...

touch ${DIRECTORY}/${FILE}

Esse comando aparece várias vezes no meu script e funciona bem em todas as instâncias, exceto em uma. Por algum motivo, em um ponto apenas, ele decide incluir a barra no nome do arquivo que está tentando criar e eu recebo o erro ...

cannot touch '/myfile.dat': Permission denied

No começo eu pensei que era apenas para baixo para a minha inexperiência (o que provavelmente é), mas depois de fazer um pouco de pesquisa, eu vi essa linha usada em inúmeros exemplos de trabalho corretamente. Não consigo entender - a mesma linha está funcionando bem em vários outros locais no meu script!

Alguém se preocupa em lançar alguma luz sobre isso? É a inconsistência que está realmente me incomodando. Os comandos que envolvem esse comando específico podem afetar o resultado?

    
por Rich 06.12.2012 / 12:45

2 respostas

2

Parece que ${DIRECTORY} está vazio. Nesse caso, toque em ${DIRECTORY}/${FILE} expandindo para touch /${FILE}

    
por 06.12.2012 / 12:51
0

Várias coisas podem estar acontecendo.

  • Talvez você digitou incorretamente DIRECTORY neste ponto, então o script está executando algo como touch ${DRIECTORY}/${FILE} . Como DIRECTORY não está definido, se $FILE for myfile.dat , isso se expandirá para touch /${FILE} (uma variável não definida é tratada como se estivesse vazia).
    Você pode fazer o shell parar com uma mensagem de erro se você tentar expandir uma variável não definida. Coloque set -u no topo do script (após a linha #! ). Você pode alternar entre unset-triggers-error e unset-is-empty com set -u e set +u .
  • Talvez a variável DIRECTORY não esteja definida ou vazia neste momento. Veja o ponto anterior.
  • Talvez você tenha acidentalmente colocado um espaço extra: touch ${DIRECTORY} /${FILE} . Em seguida, o comando touch recebe dois parâmetros, ele opera em ${DIRECTORY} (que, presumivelmente, é o nome de um diretório existente, configura a hora de modificação desse diretório para a hora atual) e engasga com /${FILE} . / li>
  • Talvez haja um espaço extra no final do valor de DIRECTORY . Por exemplo, se o valor da variável for /some/path com um espaço no final, então touch receberá dois parâmetros: /some/path e /myfile.dat . Veja o ponto anterior.

Seu script não funcionará se DIRECTORY ou FILE contiver qualquer caractere de espaço em branco ou globbing \[?* . Isso porque, quando você escreve, por exemplo $FOO , isso não se expande apenas para o valor da variável: esse valor é dividido em palavras em cada sequência de espaço em branco, e cada palavra é interpretada como um padrão curinga e substituída por nomes de arquivos correspondentes (se nenhum nome de arquivo corresponder , o padrão é deixado sozinho). Sempre use aspas duplas em torno de substituições de variáveis (e também substituições de comandos). Dentro de aspas duplas, "$FOO" se expande para apenas o valor de FOO sem mais mutilações.

touch "$DIRECTORY/$FILE"

(Veja também $ VAR vs $ {VAR} e para citar ou não citar )

Para ter uma ideia melhor do que o script está fazendo, coloque set -x após a linha #! . Isso ativou um modo de depuração em que o shell imprime cada comando antes de executá-lo. Você pode ativar e desativar os rastreios de depuração com set -x e set +x .

    
por 07.12.2012 / 01:50