Расширение параметров скрипта Bash - PullRequest
1 голос
/ 13 октября 2011

У меня есть сценарий:

#!/bin/bash
SINGLE_FILE=/tmp/blah.file
MULTIPLE_FILES=/tmp/{dir1,dir2}/*.file

cp $SINGLE_FILE $MULTIPLE_FILES /tmp/newDir

Это не удастся выполнить с:

cp: не может быть указано `/tmp/ndomdir1,dir2 innovative/*.file ':Нет такого файла или каталога

Похоже, что скрипт не расширяет подстановочные знаки в моих переменных.Так что я могу заставить этот скрипт работать с:

eval cp $SINGLE_FILE $MULTIPLE_FILES /tmp/newDir

Мой вопрос: почему скрипт не расширяет мою переменную?Кроме того, есть ли другой способ решить эту проблему, кроме использования eval?

Ответы [ 3 ]

3 голосов
/ 13 октября 2011

Сценарий - это расширение вашей переменной до значения, которое вы установили, т.е. /tmp/{dir1,dir2}/*.file, верно?

И, как вы правильно обнаружили, вам нужно попросить оболочку «снова пройти через эту строку» и заново оценить все переменные, которые вы там найдете.

Таким образом, нет другого пути, кроме eval (хорошо, вы могли бы разболтать вещи и тратить много вычислительной мощности, и по существу переделать функцию eval с вашим собственным кодом.)

Единственное, что я могу порекомендовать, - это использовать функцию отладки оболочки set -vx, чтобы лично убедиться, как она работает, т.е.

$set -vx
set -vx
>set -vx
$SINGLE_FILE=/tmp/blah.file
SINGLE_FILE=/tmp/blah.file
>SINGLE_FILE=/tmp/blah.file

$MULTIPLE_FILES=/tmp/{dir1,dir2}/*.file
MULTIPLE_FILES=/tmp/{dir1,dir2}/*.file
>MULTIPLE_FILES='/tmp/{dir1,dir2}/*.file'

$echo /tmp/blah.file '/tmp/{dir1,dir2}/*.file' /tmp/newDir
echo /tmp/blah.file '/tmp/{dir1,dir2}/*.file' /tmp/newDir
>echo /tmp/blah.file '/tmp/{dir1,dir2}/*.file' /tmp/newDir
/tmp/blah.file /tmp/{dir1,dir2}/*.file /tmp/newDir

$eval echo /tmp/blah.file '/tmp/{dir1,dir2}/*.file' /tmp/newDir
eval echo /tmp/blah.file '/tmp/{dir1,dir2}/*.file' /tmp/newDir
>eval echo /tmp/blah.file '/tmp/{dir1,dir2}/*.file' /tmp/newDir
echo /tmp/blah.file /tmp/{dir1,dir2}/*.file /tmp/newDir
>echo /tmp/blah.file '/tmp/dir1/*.file' '/tmp/dir2/*.file' /tmp/newDir
/tmp/blah.file /tmp/dir1/*.file /tmp/dir2/*.file /tmp/newDir
2 голосов
/ 13 октября 2011

Кажется, что это скобки, которые запутывают вещи здесь. IMO, это несоответствие является ошибкой в ​​оболочке - если бы у вас было MULTIPLE_FILES=/tmp/dir1/*.file, это немедленно расширило бы это. Добавьте фигурные скобки, и тогда он перестанет пытаться расширяться. Который отличается, когда вы запускаете что-нибудь еще.

Между тем, eval не является плохим решением / обходным решением. Единственное, о чем я могу подумать, - это MULTIPLE_FILES=$(echo /tmp/{dir1,dir2}/*.file), что не обязательно будет лучше.

В общем, я стараюсь избегать такого рода вещей, так как правильный синтаксический анализ оболочки затруднен, когда в именах файлов / каталогов есть пробелы. Вместо этого я стараюсь использовать find ... -print0 | xargs -0 ... как можно больше. Или прямо на другой язык сценариев, такой как perl.

1 голос
/ 13 октября 2011

Вы можете использовать массив:

SINGLE_FILE=/tmp/blah.file
MULTIPLE_FILES=( /tmp/{dir1,dir2}/*.file )
cp -t /tmp/newDir "$SINGLE_FILE" "${MULTIPLE_FILES[@]}"
...