LINUX.ORG.RU

Откуда берутся эти строки

 , ,


0

2

Всем привет!

Вот есть скрипт:

#!/opt/bin/bash
file=/volume1/usr/wsh/scripts/output.txt
IFS=$'\r\n'
while read LINE; do
cmd_fin="$(find /volume1/users/path/ -type f -name "${LINE}" -print)"
	$cmd_fin
	if $?
	then
		echo "File is exist! "$cmd_fin" " >> /var/log/temp_find_final_files.txt
	else
		echo "file not found "$LINE" " >> /var/log/temp_find_final_files.txt
	fi
done < $file

То, что он не ищет файлы это один момент. Т.е. создан заведомо существующий файл и внесен строкой в output.txt. Если просто из консоли сделать поиск, все находит, а из скрипта нет.

А вот больше интересует, почему в консоль сыпется всякое вида:

/volume1/users/path/07.06.20.pdf: command substitution: line 2: unexpected EOF while looking for matching `''
/volume1/users/path/07.06.20.pdf: command substitution: line 4: syntax error: unexpected end of file
/volume1/users/path/07.06.20.pdf: command substitution: line 2: unexpected EOF while looking for matching `]'
/volume1/users/path/07.06.20.pdf: command substitution: line 3: syntax error: unexpected end of file
/volume1/users/path/07.06.20.pdf: line 2:Ⳑ����~4ۙ���wO$ : No such file or directory

Это find из скрипта по содержимому файла что-то ищет? Подскажите, пожалуйста.

А вот больше интересует, почему в консоль сыпется всякое вида:

Твой скрипт пытается запустить файл «/volume1/users/path/07.06.20.pdf».

Deleted ()
Ответ на: комментарий от Deleted

в output.txt содержатся имена файлов.

скрипт должен брать построчно имена файлов из файла output.txt и производить поиск файла с таким именем в каталоге /volume1/users/path/ , и сообщить о наличии или отсуствии этого файла.

Хочу еще сделать, чтобы он сообщал, по какому пути располагается найденный файл, но не могу разобраться в перенаправлениях вывода команд..

Да и начать нужно с восстановления базовой функциональности

что именно ты хочешь получить вот от этой строки:

хочу чтобы она сделала поиск и исходя из результата поиска, сообщила о наличии или отсутствии файла

Aborigen1020 ()
Ответ на: пытается запустить файл от Aborigen1020

но почему?

Потому что ты так написал. Вот смотри:

cmd_fin="$(find /volume1/users/path/ -type f -name "${LINE}" -print)"

^ тут в переменную cmd_fin ты передаёшь вывод команды find, то есть список найденных файлов либо пустую строку.

	$cmd_fin

^ тут содержимое этой переменной передаётся шеллу как команда. Эффект такой же, как если это же содержимое скопировать и вставить просто в терминал. А там у тебя список файлов.

Deleted ()
Последнее исправление: Deleted (всего исправлений: 2)
Ответ на: комментарий от Aborigen1020

Например, проверять на найден ли файл, или нет

Если строка пустая (команда find ничего не вывела на stdout), то файл не найден. Если не пустая (команда find вывела список найденных файлов), то найден один или больше файлов.

Deleted ()
Ответ на: комментарий от Deleted

возможно ли проверять содержимое stdout на предмет «пустого значения»? я слабо себе это представляю.

Кажется, действую не в том направлении, нужно что-то более элегантное, чем у меня.

Aborigen1020 ()
Ответ на: комментарий от Deleted

$cmd_fin
^ тут содержимое этой переменной передаётся шеллу как команда

А возможно ли результат выполнения этой команды передать в другую переменную? Перенаправление вывода не сработает, а

cmd_fin=$(find что-то там)
a=$(cmd_fin)
echo $a
вызовет тот же самый поиск повторно. Как быть в таком случае?

Aborigen1020 ()

Кстати вот хороший способ проверить, находится ли файл финдом, без read который новички всегда используют неправильно:

# вариант попроще для понимания
if ! find -name "${FILE}" -type f | cmp -s - /dev/null; then
    echo "File is exist! ${FILE} " >> /var/log/temp_find_final_files.txt
  else
    echo "file not found ${FILE} " >> /var/log/temp_find_final_files.txt
fi

# вариант переносимый и короткий
if ! find -name "${FILE}" -type f -exec false {} +; then
    echo "File is exist! ${FILE} " >> /var/log/temp_find_final_files.txt
  else
    echo "file not found ${FILE} " >> /var/log/temp_find_final_files.txt
fi

legolegs ★★★★★ ()
Последнее исправление: legolegs (всего исправлений: 1)
Ответ на: комментарий от legolegs

без read который новички всегда используют неправильно

А что не так у автора темы с read? Он же просто для построчного чтения файла используется.

Deleted ()
Ответ на: комментарий от Deleted

Я затупил, read действительно никуда не девается. Но это плохо, см пример:

files.txt

file1
file2
dir\newfile3
file4
emptydir5\
file5
 while read LINE; do printf "'%s'\n" "$LINE"; done < files.txt
'file1'
'file2'
'dirnewfile3'
'file4'
'emptydir5file5'
while read -r LINE; do printf "'%s'\n" "$LINE"; done < files.txt
'file1'
'file2'
'dir\newfile3'
'file4'
'emptydir5\'
'file5'

Учитывая, что \ есть разделитель путей на винде, то у топикстартера он может в исходных данных оказаться и произвести аномалию.

legolegs ★★★★★ ()
sed $'s,\r,,; 1ba; i-o\n :a i-name\n $a\\)' /volume1/usr/wsh/scripts/output.txt  | xargs -r find /volume1/users/path -type f \( > /tmp/found_files.txt
grep -xvF "`sed 's,.*/,,; s,$,\r,' /tmp/found_files.txt | sort -u`" /volume1/usr/wsh/scripts/output.txt  > /tmp/missing_files.txt
Jini ★★ ()
Ответ на: комментарий от legolegs

Я затупил, read действительно никуда не девается. Но это плохо, см пример:

Вы уже выкручиваетесь. Вот же слова ТСа:

скрипт должен брать построчно имена файлов из файла output.txt и производить поиск файла с таким именем в каталоге /volume1/users/path/

Судя по всему ему вообще не нужно никакой find и $(find) вообще, а просто изучить if [[ -f «$PATH/$LINE» ]]

vodz ★★★★★ ()
Последнее исправление: vodz (всего исправлений: 1)
Ответ на: комментарий от vodz

а просто изучить

if [[ -f «$PATH/$LINE» ]]

Но мне $PATH не известен заранее, т.е. там еще несколько вложенных каталогов, а поиск будет идти только по указанному ранее пути.

Какой выход из данной ситуации? Предоставлять в условии $PATH как список каталогов из файла?

Aborigen1020 ()
Последнее исправление: Aborigen1020 (всего исправлений: 1)
Ответ на: а просто изучить от Aborigen1020

Но мне $PATH не известен заранее,
как список каталогов из файла?

Не надо на ходу переобуваться. «имена файлов из файла output.txt и производить поиск файла с таким именем в каталоге /volume1/users/path/» Так у вас в файле имена файлов, которые надо найти в указанном каталоге, или таки файлы с каталогами, которые надо найти в ещё и в любом подкаталоге? Прежде чем спрашивать советы, надо хотя бы для себя понять, чего вам надо и правильно сформулировать.

vodz ★★★★★ ()
Последнее исправление: vodz (всего исправлений: 1)

Братюнь, ты в лучших традициях лора описал свои фантазии на тему решения какой-то задачи, но не саму задачу.
Респект тебе, что помогаешь новичкам развивать в себе умение докапываться до сути

zolden ★★★★★ ()
Ответ на: комментарий от vodz

То что это не было указано явно, не значит что кто-то переобувается, иначе в скрипте был бы не find, а скорее всего ls | grep , судя по моим навыкам.

zolden

А вообще в тот момент мне не было ясно, почему скрипт смотрит в файл, а не делает поиск, поэтому задачу я не описывал полностью

Aborigen1020 ()
Ответ на: комментарий от Aborigen1020

А вообще в тот момент мне не было ясно, почему скрипт смотрит в файл, а не делает поиск, поэтому задачу я не описывал полностью

Если вы были бы способны ее описать. Ваш скрипт, который вы скомпилировали из каких-то примеров, судя по хорошему качеству первых строк кода, ничего не доказывает, что вы там чего-то понимаете, судя по вашим демонстрируемым знаниям. Ибо, он а) таки ищет, б) он не смотрит, а запускает на выполнение.

vodz ★★★★★ ()
Последнее исправление: vodz (всего исправлений: 2)

Может вам на самом деле нужен был

1) список отсутствующих файлов:
find /volume1/users/path/ -type f | grep -vf <(sed 's/\r/$/' $file)

2) список имеющихся файлов:
find /volume1/users/path/ -type f | grep -f <(sed 's/\r/$/' $file)

?

bormant ★★★★★ ()
Последнее исправление: bormant (всего исправлений: 1)

Всем большое спасибо.

legolegs

find возвращает 0 независимо от того, нашёл хоть что-то или нет.

Занимательно, спасибо.

По итогу просто вывел результат поиска в файл, и его проанализировал.

#!/opt/bin/bash
file=/volume1/usr/wsh/scripts/output.txt
IFS=$'\r\n'
while read LINE; do
cmd_fin="$(find /volume1/users/path/ -type f -name "${LINE}" -print)"
	echo "$LINE" $cmd_fin >> /var/log/find_files.txt
done < $file
Получилось так:
файл           путь ко всем найденным экземплярам
Если пути нет, то и файл не найден.

Aborigen1020 ()