Почему команда cat перенаправляет новый файл выполняется сразу?

#!/bin/sh

while read word; do
    case "$word" in
        *aa)    printf 'Got double "a": %s\n' "$word"   ;;
        *a)     printf 'Got single "a": %s\n' "$word"   ;;
        *)      printf 'Got weirdness:  %s\n' "$word"   ;;
    esac
done <file.in

Выполнение этого с примерными данными вfile.in:

Got single "a": 1a
Got double "a": 1aa
Got single "a": 2a
Got double "a": 2aa

Вы можете расширить это с помощью цикла по вашим файлам вокруг существующего whileцикла:

#!/bin/sh

for name in./*.in; do
    while read word; do
        case "$word" in
            *aa)    printf 'Got double "a": %s\n' "$word"   ;;
            *a)     printf 'Got single "a": %s\n' "$word"   ;;
            *)      printf 'Got weirdness:  %s\n' "$word"   ;;
        esac
    done <"$name"
done

Предполагается, что вводимые вами файлы соответствуют шаблону *.inи находятся в текущем каталоге.

0
06.09.2019, 20:56
1 ответ

Здесь -документ типа <<-SCRIPTдействует как строка в двойных -кавычках, поскольку в ней обрабатываются расширения. Чтобы этого не произошло, укажите разделитель:

в кавычках.
$ cat <<EOF
1+1 = $((1+1))
EOF

1+1 = 2

против

$ cat <<'EOF'
1+1 = $((1+1))
EOF

1+1 = $((1+1))

Итак, здесь:

cat <<-SCRIPT >test-$$
       ...
        osType=$(grep -Po '^NAME="\K[^"]*' /etc/os-release)

Команда grepнаходится внутри подстановки команд, которая обрабатывается, поскольку SCRIPTне заключена в кавычки, поэтому она выполняется, когда используется здесь -документ.

Здесь, с другой стороны:

cat <<-SCRIPT >test-$$
        #!/bin/bash
        rpm -q somepackage > test-$$
        rm test-$$-lock
        exit
    SCRIPT

подстановки команд нет, поэтому команды не выполняются. Часть rpm -q somepackage— это просто текст. Однако с разделителем без кавычек $$внутри документа -будет немедленно расширен до того же значения, которое используется в имени выходного файла. То есть, если PID текущей оболочки равен 1234, команда catсоздаст test-1234, содержащую строку rpm -q somepackage > test-1234.

С разделителем в кавычках $$будет оставлен как -, а результатом будет файл с именем test-1234, содержащий rpm -q somepackage > test-$$. Если вы сейчас запустите test-1234как скрипт, тогда $$будет расширен, и будет использоваться PID этой оболочки. Вероятно, оно будет отличаться от значения, использованного при создании файла.

В любом случае $$в rpm.. > test-$$и rm test-$$-lockбудут расширены до одного и того же значения.

4
28.01.2020, 02:18

Теги

Похожие вопросы