no trabalho parece estar rodando usando / bin / sh embora eu tenha um #! / bin / bash

5

Estou tentando executar um trabalho usando at e tenho um script bash (tenho #!/bin/bash como a primeira linha), mas o trabalho falha devido ao uso de [[ e ]] no script, vejo o seguinte no mail que gera:

=sh: 58: [[: not found
=sh: 58: [[: not found
=sh: 58: [[: not found
=sh: 58: [[: not found
=sh: 58: [[: not found

O /bin/sh é um link para dash , mas se eu tiver a linha she-bang como #!/bin/bash no meu script, não use bash ?

P.Se eu apenas executar o script no meu prompt bash - ele funciona bem sem erros (e tem permissões executáveis).

- EDITAR

Estou adicionando o trabalho assim:

$ at 1:30 am today -f /path/to/my/script.sh



$ which bash 
/bin/bash

$ ls -l /bin/sh
lrwxrwxrwx 1 root root 4 Mar 30  2012 /bin/sh -> dash

$ uname -a
Linux server1 3.5.0-46-generic #70~precise1-Ubuntu SMP Thu Jan 9 23:55:12 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
    
por vyom 25.08.2014 / 11:02

3 respostas

3

POSIX definiu que pode usar SHELL variável de ambiente como alternativa a /bin/sh , mas não a restringiu:

SHELL

Determine a name of a command interpreter to be used to invoke the at-job. If the variable is unset or null, sh shall be used. If it is set to a value other than a name for sh, the implementation shall do one of the following: use that shell; use sh; use the login shell from the user database; or any of the preceding accompanied by a warning diagnostic about which was chosen.

Algumas implementações de at podem lhe dar a capacidade de escolher qual shell você deseja executar, como -k para shell Korn, -c para C-shell. E nem toda implementação de at allow SHELL para substituir sh . Assim, o POSIX também garantiu que a maneira confiável de usar outro shell é explicitamente chamá-lo :

Some implementations do not allow substitution of different shells using SHELL. System V systems, for example, have used the login shell value for the user in /etc/passwd. To select reliably another command interpreter, the user must include it as part of the script, such as:

$ at 1800

myshell myscript

EOT

job ... at ... $

Uma maneira simples de usar bash para executar seu script é passar bash script como stdin para at :

echo "bash /path/to/yourscript" | at <time>

Exemplo:

echo "bash /path/to/yourscript" | at 16:30

executará bash /path/to/yourscript às 16:30 de hoje.

    
por 25.08.2014 / 11:28
2

at e batch :

read commands from standard input or a specified file which are to be executed at a later time, using /bin/sh.

POSIX define a entrada de at como:

a text file consisting of commands acceptable to the shell command language described in Shell Command Language.

Ou seja, é obrigatório para ser um script POSIX sh . O Bash permite que os Bashisms sejam executados mesmo quando é executado como sh , mas dash é estrito. O script não é executado como um executável, mas diretamente com sh , portanto, um binário arbitrário ou um script Python também não funcionarão, por exemplo.

O que você pode fazer, no entanto, é forçar você mesmo a bash de qualquer maneira. Algo como:

[ "$BASH_VERSION" ] || exec bash "/path/to/script"

na parte superior do arquivo, o script deve ser executado novamente com bash quando ainda não estiver sendo interpretado dessa maneira. O shell não irá gerar erros de sintaxe para o código que a execução não consegue, então os usos posteriores de [[ não importarão. Você pode usar $0 em vez do caminho, mas parece ser inconsistente entre at implementações e nenhuma das especificações implica que deva funcionar, então o caminho será mais confiável.

    
por 25.08.2014 / 11:19
1

Minha resposta é semelhante à de Gnouc, mas acredito ter uma explicação melhor do "por quê?" Quando você diz at … -f /path/to/my/script.sh , você está dizendo at para ler /path/to/my/script.sh . Ele copia seu script em algum lugar (provavelmente em algum lugar abaixo de /var/spool/cron ) para que atd , o daemon de at jobs, possa passar o conteúdo do script para /bin/sh . Neste ponto, a linha #!/bin/bash she-bang é apenas um comentário, e seu uso de [[…]] é um erro.

O que você quer fazer é não dar at o conteúdo do seu script, mas dê o nome , por

$ echo /path/to/my/script.sh | at 1:30 am today

ou

$ at 1:30 am today
/path/to/my/script.sh
Ctrl+D

Dessa forma, o /bin/sh verá /path/to/my/script.sh e irá executá-lo como um comando. E então a linha she-bang fará o seu trabalho, fazendo com que bash seja invocado.

P.S. Minha resposta (como a de Gnouc) tem o "recurso" que, se você mudar seu roteiro entre hoje e 1:30 da manhã hoje, atd executará a versão modificada. (Isso é diferente da sua abordagem, usando -f , onde at faz uma cópia do seu script quando você executa at .) Em particular, se você excluir ou renomear o script, nada será executado.

    
por 25.08.2014 / 20:29

Tags