Explicar as opções -path e -une

11

Eu tenho um script simples que eu entendo mais, é o comando find que não está claro. Eu tenho muita documentação, mas ela não está servindo para torná-la muito mais clara. Meu pensamento é que ele está trabalhando como um para-loop, o arquivo encontrado atualmente é trocado dentro para {} e copiados para $ HOME / $ dir_name, mas como é que a pesquisa com -caminho e -o -prune trabalho? É irritante ter essa documentação específica e relevante e ainda não saber o que está acontecendo.

#!/bin/bash
# The files will be search on from the user's home
# directory and can only be backed up to a directory
# within $HOME

read -p "Which file types do you want to backup " file_suffix
read -p "Which directory do you want to backup to " dir_name

# The next lines creates the directory if it does not exist
test -d $HOME/$dir_name || mkdir -m 700 $HOME/$dir_name

# The find command will copy files that match the
# search criteria ie .sh . The -path, -prune and -o
# options are to exclude the backdirectory from the
# backup.
find $HOME -path $HOME/$dir_name -prune -o \
-name "*$file_suffix" -exec cp {} $HOME/$dir_name/ \;
exit 0

Esta é apenas a documentação que eu sei que deveria ser capaz de descobrir.

-path padrão

O nome do arquivo corresponde ao padrão do shell. Os metacaracteres não tratam / ou . especialmente; então, por exemplo, encontre. -path "./sr*sc" imprimirá uma entrada para um diretório chamado ./src/misc (se houver). Para ignorar uma árvore de diretórios inteira, use -prune em vez de verificar todos os arquivos na árvore. Por exemplo, para pular o diretório src / emacs e todos os arquivos e diretórios abaixo dele, e imprimir os nomes dos outros arquivos encontrados, faça algo assim:

find . -path ./src/emacs -prune -o -print

Do manual do Findutils

- Ação: comando -exec; Essa variante insegura da ação -execdir é especificada pelo POSIX. A principal diferença é que o comando é executado no diretório a partir do qual a localização foi invocada, o que significa que {} é expandido para um caminho relativo começando com o nome de um dos diretórios iniciais, em vez de apenas o nome base do arquivo correspondente.

Enquanto algumas implementações de find substituem o {} somente onde ele aparece por si só em um argumento, o GNU find substitui {} onde quer que ele apareça.

E

Por exemplo, para comparar cada arquivo de cabeçalho C no diretório atual ou abaixo do diretório com o arquivo / tmp / master:

      find . -name '*.h' -execdir diff -u '{}' /tmp/master ';'
flerb
fonte
Eu acho que, se alguma coisa é uma duplicata do caminho encontrado explicada, mesmo que a resposta em localização: o ameixa não ignore o caminho especificado, tenha uma resposta que parece se aplicar a esta pergunta. Talvez as respostas explicadas pelo caminho da descoberta façam sentido para alguém mais experiente em scripts, mas elas não me ajudam. As respostas aqui apresentadas fazem mais sentido para mim até agora, mesmo que eu esteja começando a investigá-las.
flerb

Respostas:

23

-pathfunciona exatamente como -name, mas aplica o padrão ao nome do caminho inteiro do arquivo que está sendo examinado, em vez do último componente.

-prune proíbe a descida abaixo do arquivo encontrado, caso seja um diretório.

Juntando tudo, o comando

find $HOME -path $HOME/$dir_name -prune -o -name "*$file_suffix" -exec cp {} $HOME/$dir_name/ \;
  1. Começa a procurar arquivos no $HOME.
  2. Se encontrar um arquivo correspondente, $HOME/$dir_nameele não ficará abaixo dele ("remove" o subdiretório).
  3. Caso contrário ( -o), se encontrar um arquivo correspondente, *$file_suffixcopie-o para $HOME/$dir_name/.

A idéia parece fazer um backup de parte do conteúdo de $HOMEum subdiretório de $HOME. As peças com -prunesão obviamente necessárias para evitar fazer backups de backups ...

AlexP
fonte
Se eu entender: o find irá percorrer todos os diretórios em $ HOME para os quais ele tem permissão para entrar, exceto $ HOME / $ dir_name, para o qual não descerá (porque a ação de remoção será avaliada como verdadeira e a ou será não deve ser tirado), procurando por arquivos que terminem com $ file_suffix. Então, assim que encontrar um, ele executará o cp "found_file.sh" em $ HOME / $ dir_name? Além disso, -path permite um caminho para um arquivo e é útil quando você deseja localizar em diretórios e não apenas trabalhar no diretório atual?
flerb
Sua compreensão está quase correta. -pathfunciona exatamente como -name: seleciona arquivos. A diferença é que -namecombina um padrão com o nome do arquivo, enquanto que -pathcombina um padrão com o nome do caminho completo. findsempre desce em subdirectórios, a não ser impedido por -maxdepthou -pruneetc
AlexP
Oh! -path está sendo aplicado a $ HOME / $ dir_name -prune, então, é a ordem dos comandos que estava me atrapalhando, e -path é necessário para o comando prune porque ele precisa corresponder ao caminho completo do diretório removido.
flerb
@ Darren Não tenho certeza se isso é bastante preciso. -path $HOME/$dir_nameé uma ação. É um teste que verifica se o caminho do arquivo atual sendo examinado corresponde ao que $HOME/$dir_namefor. -pruneé uma ação separada. Acho que a primeira frase do seu primeiro comentário reflete com precisão como isso funciona.
David Z #
Faltava algo para vê-lo como um cano? Troquei -prune com -print e acho que o fluxo está claro agora: encontre $ HOME | -path $ HOME / $ dir_name | -print
flerb
4

Faz parte do comando find, a instrução -exec.

Ele permite que você interaja com o arquivo / diretório encontrado pelo findcomando.

find $HOME -path $HOME/$dir_name -prune -o -name "*$file_suffix" -exec cp {} $HOME/$dir_name/ \;

find $HOME significa encontrar arquivos / diretórios em $ HOME

Para entender -path <some_path>, veja `find -path` explicado

Para entender -prune, consulte /programming/1489277/how-to-use-prune-option-of-find-in-sh

-osignifica OR, então -path <some_path>OR-name *$file_suffix

-exec significa executar o comando.

cp {} $HOME/$dir_name/ copie todos os arquivos correspondentes a $HOME/$dir_name/

\;significa encerrar o -execcomando

thecarpy
fonte