Eu tenho muitos arquivos em um diretório:
$ ls
file000001
file000002
# ... truncated ...
file999999
Estou calculando o md5sum dos arquivos assim e finalmente despejando-o em um arquivo:
hashes=''
for file in $(ls); do
hashes+=$(md5sum $file)
hashes+="\n"
done
echo "$hashes" > hashes.txt
Agora, gostaria de pressionar Ctrl + C enquanto a execução do script está dentro do for
loop e ter o conteúdo hashes
despejado no arquivo hashes.txt. Isso é possível?
(Sim, posso anexar o md5sum a hahes.txt
cada vez que o md5sum de cada arquivo for calculado, mas pretendo fazer dessa maneira (como mostrado acima).)
Observe que o código de exemplo acima é terrível. Na verdade, usei md5sum como exemplo; Estou fazendo outras coisas. A intenção da minha pergunta é realmente descobrir como fazer o Ctrl + C funcionar.
BTW, eu não usaria
ls
para obter a lista de arquivos, mas algo comofor file in *; do
.trap break INT
antes do seu loop:Corrigi algumas coisas duvidosas no seu script (
$(ls)
,"\n"
).FWIW, tal "interrupção não local" não funciona em
mksh
oryash
, mas funciona embash
,dash
e .zsh
ksh93
Você nunca deve usar a saída de
ls
como entrada para outro programa. Não funciona (para qualquer definição de "trabalho" que inclua os conceitos de confiabilidade ou segurança), e nunca há necessidade de fazê-lo porque o globbing do shell (ou seja, expansão curinga) faz o trabalho que você está tentando fazer mau usols
. Consulte Por que não analisarls
(e o que fazer em vez disso)? .Se você precisar fazer algo semelhante, use
find ... -exec {} +
oufind ... -print0 | xargs -0r ...
em vez dels
- qualquer um deles realmente funcionará e funcionará com segurança, não importa quais caracteres estejam nos nomes dos arquivos.Seu
for
loop deve ser escrito como:Você nem precisa de um
for
loop, a menos que faça outra coisa com cada um$file
dentro do loop.Aqui estão algumas maneiras alternativas de fazer o que seu loop for faz, armazenando a saída de
md5sum
em uma matriz chamadahashes
e imprimindo-a:usando
printf
:Observe que há dois
%s
separados por dois espaços naprintf
string de formato. Isso produzirá a mesma saída quemd5sum
ele mesmo.BTW, você pode ver como as entradas são armazenadas na matriz com
typeset -p
:O shell dividiu a saída de
md5sum
em palavras (conforme definido pelo valor da$IFS
variável do shell) e colocou cada "palavra" em um elemento separado do array.usando
tee
:Sabendo disso, a resposta da armadilha de Lasse Kliemann poderia ser escrita como:
No entanto, você nem precisa de uma armadilha aqui.
md5sum
withtee
fará o que você quiser - ou seja, preencher$hashes
E simultaneamente ohashes.txt
arquivo.Ou, se você não quiser usar uma matriz:
Aqui estamos usando
tee
a opção de-a
(--append
) porque estamos executandomd5sum
em um loop e não queremos que cada iteração sobrescreva ohashes.txt
arquivo.Nota: Isso sempre terá uma linha extra em branco no final da
$hashes
string, aumentando a contagem de linhas em 1. Este não será o caso ao usar um array.