Como deixar o comando de execução do Netcat após a conclusão da transferência de arquivos?

5

Eu quero deixar o netcat no meu servidor executar um script que funcione em um arquivo que acabou de ser enviado e que a saída desse script seja enviada como resposta ao cliente. Minha abordagem é:

No site de recebimento:

nc.traditional -l -p 2030 -e "./execute.sh" > file.iso

No site de envio:

cat file.iso - | nc.traditional -w 1 serverAddress 2030

Neste momento, o site de recebimento executa o script antes que o arquivo seja completamente transferido, mas envia a saída do script de volta ao site de envio e fecha a conexão. Eu gostaria que o site recebedor esperasse até que o arquivo fosse completamente transferido antes de executar o script.

    
por Snagnar 14.05.2018 / 13:33

1 resposta

4

Você precisa de alguma forma de o terminal receptor reconhecer o final do arquivo transferido. Com cat file - | nc no lado de envio, o fluxo de dados através do pipe não fará separação entre o conteúdo do arquivo e o que o usuário digitar no terminal ( cat - lê o terminal). Além disso, por padrão, o netcat não reage a um EOF em sua entrada, mas podemos usar -q para enviar o EOF.

O script de recebimento pode ser assim:

#!/bin/bash
filename=$1
cat > "$filename"

hash=$(shasum "$filename" |sed -e 's/ .*//')
printf "received file \"%s\" with SHA-1 hash %s\n" "$filename" "$hash"

O cat lê a entrada até EOF, salvando o arquivo. O que quer que se segue, é executado depois que o arquivo é recebido. Aqui, o script envia de volta o hash SHA-256 dos dados recebidos.

Então, no lado do recebimento, execute:

$ nc.traditional -l -p 12345 -c "./receivefile.sh somefilename"

e no lado do envio:

$ cat sourcefile | nc.traditional -q 9999 localhost 12345
received file "somefilename" with SHA-1 hash 3e8a7989ab68c8ae4a9cb0d64de6b8e37a7a42e5

O script acima usa o nome do arquivo como argumento, então usei -c em vez de -e , mas é claro que você também pode redirecionar a saída de nc para o arquivo de destino, como você fez na pergunta .

Se você quiser enviar o nome do arquivo do lado de envio também, pode fazer algo assim no lado de recebimento:

#!/bin/bash
read -r filename
[[ $filename = */* ]] && exit 1       # exit if the filename contains slashes
cat > "$filename"
echo "received $filename"

e, em seguida, envie com (echo filename; cat filename) | nc -q 9999 localhost 12345 . (Você pode querer ter muito mais cuidado com o nome do arquivo fornecido com controle remoto aqui. Ou simplesmente usar algo projetado para transferência de arquivos, como scp .)

Em vez de usar nc , você poderia fazer isso de maneira semelhante com o SSH:

cat filename | ssh user@somehost receive.sh
    
por 14.05.2018 / 14:08