
Tudo descrito abaixo é feito por meio de um script Bash.
Desejo capturar o estado de um conjunto definido de arquivos em um conjunto definido de hosts remotos. O "estado" de um arquivo depende do tipo de arquivo:
- Arquivo normal: caminho completo, conteúdo do arquivo, modo, proprietário, grupo
- Link simbólico: caminho completo do próprio link, caminho apontado, modo (sempre 777), proprietário, grupo
- Diretório: caminho completo, modo, proprietário, grupo
Ao criar um arquivo local para representar o estado de um arquivo remoto, distingo entre arquivos com o mesmo caminho completo, mas que diferem em hosts diferentes, anexando ao nome do arquivo local um hash das características listadas acima. Em seguida, eu tar o arquivo remoto (não recursivamente, para que, no caso de um diretório, eu obtenhaapenaso diretório), canalize-o através do SSH, descompacte-o em minha máquina local e transfira-o para o nome do arquivo com um hash anexado. Eu uso alcatrão porque preserva as características que me interessam.
HASH=$(ssh -n "$ONE_HOST" "{ cat $ONE_FILE_PATH; stat -c \"%a %u %g %F\" $ONE_FILE_PATH; } | sha512sum")
ONE_HASH=${ONE_HASH:0:20}
TARGET_FILENAME_FOR_COPY="$FILENAME"."$ONE_HASH"
TARGET_PATH_FOR_COPY="$TARGET_DIRECTORY_FOR_COPY"/"$TARGET_FILENAME_FOR_COPY"
ssh -n "$ONE_HOST" \
"tar -C $DIRECTORY --no-recursion -cf - $FILENAME" | \
tar -xf - -C "$TARGET_DIRECTORY_FOR_COPY"
mv "$TARGET_PATH_UNHASHED" "$TARGET_PATH_FOR_COPY"
Tudo isso está no lugar e funcionando.
Agora, para o caso dearquivos normais, tenho uma necessidade adicional de lidar com arquivos confidenciais cujo conteúdo não desejo copiar (embora o conteúdo continue a ser representado no hash). Meu objetivo é criar exatamente o mesmo arquivo local que criaria no processo descrito acima, mas que o arquivo esteja vazio em vez de conter o conteúdo do arquivo remoto.
Nota: não consigo copiar o arquivo e depois esvaziar a cópia do conteúdo. Por ser um arquivo confidencial, seu conteúdo não deve ser transferido pela rede.
Não conheço uma maneira de fazer com que o tar transfira um "shell" de um arquivo normal que tenha o modo, o proprietário e o grupo do arquivo, mas omita o conteúdo do tarball. A menos que alguém conheça um truque para fazer com que o tar faça isso, acho que terei que procurar algum mecanismo diferente do tar.
Como posso conseguir isso mais facilmente?
ATUALIZAÇÃO #1
Uma abordagem que estou tentando é primeiro fazer uma cópia temporária do arquivo (usandocp-ppara preservar os atributos de arquivo que me interessam) no sistema remoto, esvazie esse arquivo temporário de conteúdo (comtruncar -s 0) e copie-o para minha máquina local com tar/ssh conforme descrito acima. Isso é estranho e deselegante. Espero encontrar uma maneira de fazer isso sem recorrer ao uso de um arquivo temporário.
Responder1
Você pode montar um arquivo vazio sobre os arquivos confidenciais antes de executar o tar.
touch /tmp/emptyfile
mount --bind /tmp/emptyfile /home/user/.ssh/id_rsa
Ou algo semelhante.