A criação de arquivos não ocorrerá dentro de uma função em um arquivo originado

2

No Ubuntu 16.04 xenial com Bash 4.3.48 e LEMP , criei uma função de conforto para criar um arquivo de informações do php (para conhecer melhor o meu ambiente de php) e, em seguida, excluí-lo após 2 horas. mas estou tendo um problema ao chamar essa função do terminal.

Etapas para reproduzir meu problema

1) Crie um arquivo com uma função:

#!/bin/bash
drt="/var/www/html"

pif() {
    cat > "$drt"/info.php <<< "<?php phpinfo();"
    rm "$drt"/info.php | at now + 2 hours
}

2) Origem desse arquivo.

3) Chame a função no terminal:

pif

Infelizmente, nenhum arquivo com o nome info.php foi criado para mim em /var/www/html . Eu verifiquei isso.

Aqui está o traço completo para executar a função desta forma ( pif ):

+ pif
+ cat
+ at now + 2 hours
+ rm /var/www/html/info.php
warning: commands will be executed using /bin/sh
job 17 at Fri Apr  6 05:43:00 2018

Por outro lado, quando eu tento criar o arquivo não de uma função, apenas executando:

cat > "$drt"/info.php <<< "<?php phpinfo();"

O arquivo é criado bem.

Minha pergunta

Por que a execução direta do terminal funcionou, mas a execução de uma função contendo o código falhou?

Atualizar

1) Eu tenho permissões de gravação para /var/www/html .

2) Eu obtive o arquivo por:

source myFunctions.sh

3) A saída de type -a pif é:

pif is a function
pif ()
{
    cat > "$drt"/info.php <<< "<?php phpinfo();";
    rm "$drt"/info.php | at now + 2 hours
}
    
por user9303970 06.04.2018 / 05:38

2 respostas

3

Sua função cria info.php , mas a exclui imediatamente.

Depois de criar o arquivo info.php , parece que você pretende que o próximo comando programe sua exclusão:

rm "$drt"/info.php | at now + 2 hours

Mas não é isso que está acontecendo. Que executa o comando rm agora, então canos sua saída padrão (para a qual nada seria escrito normalmente, pois rm é bem-sucedido silenciosamente por padrão ) para a entrada padrão do comando at .

Se você realmente precisa que essa função de shell agende a exclusão do arquivo, forneça o comando como texto na entrada padrão de at ou programe um comando que execute um script separado que exclua o arquivo. Veja em (1) para detalhes sobre como agendar comandos para executar com at .

Observe que você pode realmente ver, a partir do seu rastreamento, que isso é o que estava acontecendo:

+ at now + 2 hours
+ rm /var/www/html/info.php

Os comandos em um pipeline são executados de forma assíncrona. Esse rastreamento mostrou que o shell se comportou como deveria quando você deu dois comandos separados por | . Ele executou o comando at que apareceu no lado direito do canal para que ele pudesse receber dados do comando rm . Em seguida, ele imediatamente executou o comando rm . Quando isso aconteceu, o comando rm removeu o arquivo. Para evitar isso, você deve informar at para executar esse comando mais tarde, não executá-lo imediatamente em um pipeline.

Se você quiser usar algo parecido com o que tem, e desde que o valor de drt (que é /var/www/html em seu exemplo) não contenha espaços ou outros caracteres que serão tratados especialmente por /bin/sh (que at usa para executar o comando), então você pode usar:

at now + 2 hours <<<"rm -- $drt/info.php"

Se o valor de drt for conhecido por não iniciar com - , o argumento -- poderá ser omitido com segurança. Na sua situação, onde você parece estar no controle de $drt , isso parece uma aposta bastante segura.

Você pode achar conveniente testar seus comandos at programando-os para serem executados em um momento mais curto, como imediatamente ( at now ) ou em um minuto ( at now + 1 minute ).

    
por 06.04.2018 / 06:24
1

Eu aceitei a resposta de Eliah acima e acho que ela deve ser manuseada, mas aqui está a explicação que criei para mim mesmo, em relação a um código um pouco diferente que eu usei particularmente.

Por que o código acima estava errado:

Parece que meu comando falhou devido à falta de echo .

Considere o meu comando original:

rm "$drt"/info.php | at now + 2 hours

O que aconteceu é que o rm foi executado diretamente após a criação do arquivo, e somente então , um at vazio foi executado.

Em um diagrama ainda mais simples:

1) Create a phpinfo with an here-string.

2) Delete phpinfo with rm (nothing is further piped anywhere).

3) Wait 2 hours (for nothing, in this case).

Um código correto

O que eu deveria ter feito (e que funciona bem e eu verifiquei isso): é isso:

echo "rm $drt/info.php" | at now + 2 hours

O diagrama para este comando é este:

1) Create a phpinfo with an here-string.

2) Echo an rm command but pipe the output of the echo into the following (at) command.

3) rmat now + 2 hours.

Conclusão

Ao usar um código semelhante ao meu, certifique-se de envolver o comando que deseja agendar com at com echo "" , se você trabalhar no paradigma de do X at now + y time (from now) , de acordo com o exemplo de código acima.

    
por 06.04.2018 / 07:43