Используя коннекторы после находят команду

Я хочу, чтобы мой удар распечатал 'найденный', только если что-то найдено, с помощью команды находки. Но использование && не помогает: даже если найденный ничем, я становлюсь 'найденным' распечатанным. Пример:

$ pwd
/data/data/com.termux/files/home/test/test1/test4
$ ls
xaa  xab
$ find . -name xac && echo 'found'
found
$ find . -name xaa && echo 'found'
./xaa
found
10
задан 30 October 2017 в 22:37

2 ответа

Можно сделать find самостоятельно печать found:

find . -name xac -printf "found\n" -quit

-quit сделает find выход после первого соответствия, таким образом, found только печатается самое большее однажды.

На подобном потоке на Unix & Linux (делают, находят сбой, когда ничто не было найдено), я использовал grep -qz возвратить ненулевой статус выхода если find найденный ничем:

find /some/path -print0 -quit | grep -qz .

Который можно использовать для построения составного использования команд && или if:

find /some/path -print0 -quit | grep -qz . && echo found
18
ответ дан 23 November 2019 в 04:17

ответ muru является соответствующим и хорошо подходящим для случаев, где мы хотим распечатать что-то, если файл найден. Для общего случая, когда мы хотим выполнить внешнюю команду, такой как echo, мы могли использовать -exec флаг.

$ find . -name 'xac' -exec echo "I found " {} \; -quit             
I found  ./xac

{} часть передает имя файла команде между -exec и \; как аргументы. Отметьте \ прежде ; - это препятствует тому, чтобы оболочка неправильно истолковала it; в оболочке, заключительная точка с запятой показывает конец команды, но при выходе с наклонной чертой оболочка будет рассматривать его как литеральный текст, который будет передан find команда и найти команду это служит закрытием -exec аргументы флага.


Для построения условных выражений if found do this; else do that вид, мы могли использовать команду substition $() и test команда (иначе [ ):

$ [ "x$(find . -name 'noexist' -print -quit)" != "x" ] && echo "found" || echo "not found"                                                                                              
not found

$ [ "x$(find . -name 'xac' -print -quit)" != "x" ] && echo "found" || echo "not found"                                                                                                  
found

Обращение к комментарию Dan

Dan в комментариях спросил:

Не отозвался бы эхом "Я нашел {}" быть лучше, чем эхо, "Я нашел" {}? Возможно, для эха хорошо, но если кто-то копирует команду и заменяет эхо другой командой, у них может быть проблема

Давайте поймем проблему сначала. Обычно, в оболочках существует понятие разделения слова, что означает неупомянутые переменные, и позиционные параметры будут расширять и рассматривать как отдельные объекты. Например, если у Вас есть переменная var и это содержит hello world текст, когда Вы делаете touch $var оболочка разломает его на два отдельных объекта hello и world и touch поймет это, как будто Вы пытались создать 2 отдельных файла; если Вы делаете touch "$var", затем оболочка будет рассматривать hello world как одна единица, и touch создаст один файл только. Это важно, чтобы понять, что это происходит только из-за того, как работают оболочки.

В отличие от этого, find не страдает от такого поведения, потому что команды обрабатываются find самостоятельно и выполняемый execvp() системный вызов, таким образом, нет никакой включенной оболочки. В то время как фигурные скобки действительно имеют особое значение в оболочках, потому что они появляются посреди find команда, а не в начале, они не несут особого значения для окружения в этом случае. Вот пример. Давайте создадим несколько трудных имен файлов и попытаемся передать их как аргумент stat команда.

$ touch with$'\t'tab.txt with$' 'space.txt with$'\n'newline.txt

$ find -type f -exec stat -c "%F" {} \; -print                                                                                                                         
regular empty file
./with?newline.txt
regular empty file
./with space.txt
regular empty file
./with?tab.txt

Как видете, stat получает трудные имена файлов, превосходные с find, который является одной из главных причин, почему рекомендуется для использования в портативных сценариях, и особенно полезное, когда Вы пересекаете дерево каталогов и хотите сделать что-то с именами файлов, которые могли бы потенциально иметь специальные символы в них. Поэтому не необходимо заключить фигурные скобки в кавычки для команд, выполняемых в find.

Это - другая история, когда оболочка принимает участие. Иногда необходимо использовать оболочку для обработки имени файла. В этом случае заключение в кавычки будет действительно иметь значение, но важно понять, что это не проблема находки - это - оболочка, которая делает разделение слова.

$ find -type f -exec bash -c "stat {}" sh \;   
stat: cannot stat './with': No such file or directory
sh: line 1: newline.txt: command not found
stat: cannot stat './with': No such file or directory
stat: cannot stat 'space.txt': No such file or directory
stat: cannot stat './with': No such file or directory
stat: cannot stat 'tab.txt': No such file or directory

Таким образом, когда мы заключаем в кавычки в оболочке, она будет работать. Но снова, это важно для оболочки, нет find.

$ find -type f -exec bash -c "stat -c '%F' '{}'" sh \;                                                                                                                 
regular empty file
regular empty file
regular empty file
13
ответ дан 23 November 2019 в 04:17

Другие вопросы по тегам:

Похожие вопросы: