Подтвердить что ты не робот

Как передать параметр подстановки в файл bash

Я пытаюсь написать bash script, который позволяет пользователю передавать путь к каталогу с помощью подстановочных знаков.

Например,

bash show_files.sh *

при выполнении в этом каталоге

drw-r--r--  2 root root  4.0K Sep 18 11:33 dir_a
-rw-r--r--  1 root root   223 Sep 18 11:33 file_b.txt
-rw-rw-r--  1 root root   106 Oct 18 15:48 file_c.sql

выводит:

dir_a
file_b.txt
file_c.sql

Как сейчас, он выводит:

dir_a

содержимое show_files.sh:

#!/bin/bash

dirs="$1"

for dir in $dirs
do
    echo $dir
done
4b9b3361

Ответ 1

Родительская оболочка, вызывающая bash show_files.sh *, расширяет * для вас.

В вашем script вам необходимо использовать:

for dir in "[email protected]"
do
    echo "$dir"
done

Двойные кавычки гарантируют правильную обработку нескольких пробелов и т.д. в именах файлов.

См. также Как перебрать аргументы в оболочке bash script.


Потенциально запутанное дополнение

Если вы действительно уверены, что хотите, чтобы script расширил *, вы должны убедиться, что * передано script (заключено в кавычки, как в других ответах), а затем убедитесь, что он расширен в правой части обработки (что не является тривиальным). В этот момент я бы использовал массив.

names=( [email protected] )
for file in "${names[@]}"
do
    echo "$file"
done

Я не часто использую [email protected] без двойных кавычек, но это один раз, когда это более или менее правильная вещь. Трудная часть состоит в том, что он не будет обрабатывать карты с пробелами в очень хорошем состоянии.

Рассмотрим:

$ > "double  space.c"
$ > "double  space.h"
$ echo double\ \ space.?
double  space.c double  space.h
$

Это прекрасно работает. Но попробуйте передать это как wild-card для script и... ну, пусть просто скажу, что в этот момент становится сложно.

Если вы хотите извлечь $2 отдельно, вы можете использовать:

names=( $1 )
for file in "${names[@]}"
do
    echo "$file"
done
# ... use $2 ...

Ответ 2

Цитировать wild-card:

bash show_files.sh '*'

или сделайте свой script принятым список аргументов, а не только один:

for dir in "[email protected]"
do
    echo "$dir"
done

Лучше итерации непосредственно над "[email protected]' вместо того, чтобы назначать его другой переменной, чтобы сохранить свою особую способность удерживать элементы, которые сами содержат пробелы.