У меня есть следующий сценарий оболочки, и они спрашивают меня, как работает и каковы параметры $ 1 и $ 2.
#!/bin/bash
for i in `sort $1`; do
if grep $2 $i > /dev/null; then
echo A
cp $i /tmp
exit
fi
done
echo B;
Мой вопрос таков: $ 1 не может быть каталогом, потому что вы не можете сортировать по каталогам. Следовательно, это должен быть файл. Но функция «for i in file» подразумевает, что мы будем работать для каждой строки, а инструмент grep не работает со строками.
Я считал, что это должен быть файл, содержащий файлы, но пока я могу думать только о файлах tar, и он не работает с ними.
Спасибо!
(Тем не менее, строчно-ориентированные файлы в целом не могут безопасно использоваться для хранения списков произвольных имен файлов, потому что файлы могут иметь имена, содержащие символы новой строки. Единственное безопасное хранилище - для произвольных имен файлов, таких как произвольные строки C, переменные среды и т. д. разделен NUL).
Кроме того, непонятно, о чем вы на самом деле спрашиваете. Это для объяснения того, как работает этот код? У него не работает корректно - битый. (Более того, чем я уже описал - если у вас есть * в виде строки в вашем файле, она будет заменена списком всего в вашем текущем рабочем каталоге).
... вы говорите: «У меня такой вопрос», но то, что следует далее, является утверждением, а не вопросом.
Также см. Что делать с вопросами типа «Я не понимаю, как работает этот код?» в Meta StackOverflow - консенсус состоит в том, что такие вопросы следует закрывать как «непонятно, о чем вы спрашиваете» или «слишком широко».





sort $1, скорее всего, означает, что $1 содержит путь к файлу. Скорее всего, содержимое файла - это пути к другим файлам. В его некотируемой форме он будет подвергаться разбиению на слова и расширению глобуса. Это либо недосмотр, либо предполагаемое поведение (например, он расширит 'dat?.lst' до списка файлов, как указано в комментариях).
Цикл for предполагает, что ни один из этих путей не содержит каких-либо неудобных символов (пробелов, глобальных символов, таких как *), и просматривает каждое слово в отсортированном выводе.
$2 (который на самом деле должен быть "$2") - это шаблон для поиска в файле $i. Если содержимое файла соответствует шаблону, файл копируется на /tmp, и сценарий завершается.
Учитывая предостережение не работать с именами файлов, содержащими символы новой строки, самым простым исправлением было бы:
#!/bin/bash
sort "$1" | while read -r file; do
if grep -q "$2" "$file" 2>/dev/null; then
echo A
cp "$file" /tmp
exit
fi
done
Это предполагает, что скрипту передается путь к файлу в качестве первого аргумента, например:
/path/to/first/file
/path/to/second/file
И регулярное выражение в качестве второго аргумента с экранированием $, чтобы оболочка не пыталась их расширить.
Изменяет ли $ 1 или "$ 1" семантику программы. Может быть, автор хочет передать "dat? .Lst" в качестве параметра, который нужно расширить?
@userunknown: тогда это был бы действительно неудобный интерфейс. В этом случае сценарий должен обрабатывать несколько аргументов и позволить оболочке выполнить подстановку; тогда лучше перепроектировать интерфейс, используя шаблон в качестве первого аргумента, а оставшимися аргументами будут файлы. Тогда использование будет script thing-to-match file1 file2 file3 и разрешить script thing-to-match dat?.lst.
@userunknown: поскольку автор сценария даже не удосужился процитировать расширение $2 для оператора grep, я бы сказал, что это скорее ошибка сценариста, чем фактическая особенность дизайна.
@gniourf_gniourf: AFAIK, вопрос - это вопрос интервью, где вы должны ответить, что делает сценарий, а не как его улучшить.
!/bin/bash
for i in `sort $1`
do
if grep $2 $i > /dev/null
then
echo A
cp $i /tmp
exit
fi
done
echo B;
Вероятно, первый параметр - это имя файла или список имен файлов без пробелов, который сам содержит список имен файлов. $ 2 - это ключевое слово, которое ищется в этих файлах, которые сначала были отсортированы по имени.
Первое совпадение приводит к копированию этого файла в / tmp - вероятно, для дальнейшей обработки, а также к эхо-сообщению A и завершению программы. Если соответствующий файл не найден, печатается другое сообщение.
Обратите внимание, что маскировка $ 1 выглядит следующим образом:
for i in $(sort "$1")
do
предотвратит распространение подстановочных знаков,
script "dat-?.lst" foobar
и, возможно, сломать сценарий, поэтому я буду осторожен с предложениями по его улучшению.