Estou tentando obter a data da última modificação de um arquivo com este comando
TM_LOCAL=`ls -l --time-style=long-iso ~/.vimrc | awk '{ print $6" "$7 }'`
TM_LOCAL tem um valor como "2012-05-16 23:18" após a execução desta linha
Também gostaria de verificar o PIPESTATUS para ver se houve um erro. Por exemplo, se o arquivo não existe, ls
retorna 2. Mas $?
tem o valor 0, pois tem o valor de retorno de awk
.
Se eu executar este comando sozinho, posso verificar o valor de retorno de ls olhando para ${PIPESTATUS[0]}
ls -l --time-style=long-iso ~/.vimrc | awk '{ print $6" "$7 }'
Mas $PIPESTATUS
não funciona como eu esperava, se eu atribuir a saída a uma variável, como no primeiro exemplo. Nesse caso, a $PIPESTATUS
matriz possui apenas 1 elemento, o mesmo que$?
Portanto, a questão é: como posso obter os dois $PIPESTATUS
e atribuir a saída a uma variável ao mesmo tempo?
Use
set -o pipefail
inbash
para obter o código de saída diferente de zero à direita em uma sequência de comandos canalizada como$?
. Deman bash
:Então você pode simplesmente acessar
$?
. Useset +o pipefail
para desativar novamente.fonte
Suponho que o problema aqui é que o PIPESTATUS desaparece completamente assim que você executa um comando. Você pode obter a matriz completa do PIPESTATUS na versão 2 ou superior do bash desta maneira:
Em seguida, o acesso
${status[0]}
,${status[1]}
etc.fonte
O principal problema com "o que você espera" é que um comando entre aspas é executado em uma subshell;
$PIPESTATUS
existe lá e o status retornado segue as mesmas regras como se você executasse um único executável (ou shell script). O status do comando backquote é oawk
status mais à direita ( ).Para implementar o que Daniel Beck disse, defina a
pipefail
opção no subshell da seguinte forma:TM_LOCAL=`set -o pipefail; ls -l --time-style=long-iso ~/.vimrc | awk '{ print $6" "$7 }'`
agora o status armazenado$?
posteriormente será o status dels
(se não for zero).No entanto, acho que um
if [ -f ~/.vimrc ];
teste ... explícito seria mais legível.Você não pode obter saída em uma variável e
PIPESTATUS
retornar sem um arquivo temporário para o primeiro ou organizar o último em uma sequência.fonte
Eu queria enviar email do cron cron apenas se o status de saída não fosse zero
O truque é que, para obter o stdin para o final do pipeline, é necessário colocá-lo em um subshell - mas isso parece ocultar o valor PIPESTATUS ...
O teste cron cospe alguma saída e sai com 1 ou 0 ..
UPDATE: o PIPESTATUS não fica visível até que o comando pipeline seja processado
fonte
Uma opção é verificar a existência do seu arquivo antes de obter seu horário de modificação com uma chamada para
stat
. Comostat
retorna um pouco mais do que você deseja no carimbo de data e hora, você pode apará-lo usando a expansão de parâmetros.Com o GNU
stat
(por exemplo, no Linux), você pode executar:No Mac OS X e em outros sistemas BSD, a
stat
sintaxe difere e pode especificar um formato de hora:fonte
$TM_LOCAL
é segura. Só é seguro se você espera que ele não tenha um valor anterior. Digamos que o valor era anteriormente2020-02-27 17:14
e não há~/.vimrc
arquivo. Você então teria2020-02-27 17
. Portanto, eu amarraria essas duas linhas com uma adicional&&
ou (de preferência, porque isso não é tão legível) usar umaif
estrofe.