LINUX.ORG.RU

Проблема с эвалом

 ,


0

1

Часть скрипта:

if [...]; then OPTS='--acls --selinux --xattrs'

eval tar fpx \"$ARCHIVE\" \"${FILES[@]}\" $OPTS

eval нужен, чтобы $OPTS правильно раскрывался.
Проблема в том, что "${FILES[@]" правильно не раскрывается, если их несколько, или в именах есть пробелы.

Как быть? Может, что-то сделать с IFS, или printf'ом как-то филес раскрыть в кавычках?

★★★★★

tar fpx "$ARCHIVE" "${FILES[@]}" $OPTS

И не надо никакого eval, и не надо оставлять впоследствии трудно отлавливаемые shell injection.

"$ARCHIVE" раскрывается в одно слово, потому что в кавычках.

"${FILES[@]}" раскрывается в отдельные слова-элементы массива, потому что bash array + [@] и в кавычках.

$OPTS раскрывается в слова, из которых состоит, потому что кавычек нет.

Если не верите, передайте аргументы скрипту типа perl -E'say join " ", map ">>>$_<<<", @ARGV' -- my args "something in quotes" "${array[@]}" whatever и посмотрите на результат.

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

действительно, eval не нужен.
проблема была в том, что менял дефолтный IFS.
как правильно возвращать дефолтный IFS? только через промежуточный OLD_IFS="$IFS"?
потому что через IFS=$"\n\t " не возвращается нормально

teod0r ★★★★★ ()
Ответ на: комментарий от teod0r
$ echo -n $"\n\t " | hd # двойные кавычки, неправильно
00000000  5c 6e 5c 74 20                                    |\n\t |
00000005
$ echo -n $'\n\t ' | hd # кавычки одинарные, но значение неправильное
00000000  0a 09 20                                          |.. |
00000003
$ echo -n "$IFS" | hd # какое значение должно быть?
00000000  20 09 0a                                          | ..|
00000003 # ответ: $' \t\n'

Но я бы сделал либо через OLD_IFS, либо через local внутри функции.

anonymous ()