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