У меня есть эта переменная:

toto=123456

Почему touch "$toto.hihi.log" работает и создает файл с именем 123456.hihi.log

Но touch "$totohihi.log" ничего не делает?

2
Albizia 21 Май 2018 в 13:04
1
Вы также можете сделать touch $toto\hihi.log или touch $toto'hihi.log' или touch "$toto"hihi.log
 – 
αғsнιη
22 Май 2018 в 08:26

4 ответа

Лучший ответ

Тебе нужно

touch "${toto}hihi.log"

Проблема в том, что без фигурных скобок оболочка не может знать, сколько символов входит в имя переменной. Таким образом, он рассматривает все допустимые символы как часть имени. В данном случае это все до .; то есть оболочка использует несуществующую переменную $totohihi.

В общем, полезно использовать опцию оболочки -x, чтобы увидеть, что происходит:

set -x
touch "$totohihi.log"
    + touch .log
7
Hauke Laging 21 Май 2018 в 13:08
Привет, Хауке, я хочу знать, как установить и использовать переменную для одной строки? Например. n=2 touch "ab${n}.txt" не получает ab2.txt, но получает ab.txt.
 – 
Rick
16 Мар 2019 в 17:15
1
n=2 touch запускает touch с переменной среды n. Это не то, что вы хотите. Вы хотите, чтобы оболочка расширяла ${n}, поэтому n должна быть определена в контексте оболочки: n=2 ; touch "ab${n}.txt"
 – 
Hauke Laging
20 Мар 2019 в 19:21
Хорошо, понятно, мне нужна запятая, спасибо, @Hauke ​​:).
 – 
Rick
25 Мар 2019 в 07:22

Это так, он расширяет $totohihi до пустой строки, а затем запускает touch ".log" (при условии, что переменная не была установлена ​​где-либо еще). Попробуйте посмотреть, что говорит ls -l .log.

Как упоминалось в других ответах, вам нужно заключить имя переменной в фигурные скобки, если следующие символы могут быть частью имени переменной, поэтому touch "${toto}hihi.log". Обратите внимание, что символ подчеркивания также допустим в именах переменных вместе с буквами и цифрами, поэтому "${toto}_hihi.log" также понадобятся фигурные скобки.

3
ilkkachu 21 Май 2018 в 13:09

$totohihi.log означает переменную с именем totohihi

Чтобы он работал, используйте

${toto}hihi.log

Этот ответ stackoverflow имеет хорошее объяснение

1
mkmayank 21 Май 2018 в 13:08

Shell знает, что $toto — это переменная со значением 123456.
Следовательно, везде, где он находит $toto, он заменяет его на 123456.
Таким образом, в случае $toto.hihi.log оболочка заменяет $toto на 123456, поскольку . похожа на оператор конкатенации и создает файл, как и ожидалось.

Однако в случае $totohihi.log оболочка не находит никакой переменной с именем $totohihi и, следовательно, заменяет ее пустой строкой, что приводит к созданию файла .log. Вы можете найти его с ls -a или ls .log, так как файлы, начинающиеся с ., являются скрытыми файлами и не могут быть просмотрены с помощью простой команды ls.

Если вам нужно создать файл с именем 123456hihi.log, вам нужно будет поместить $toto в фигурные скобки как ${toto}hihi.log, как упоминалось другими в предыдущих ответах.

-1
Bhagyesh Dudhediya 22 Май 2018 в 08:17
Точка — это просто точка, а не оператор конкатенации. В стандартном синтаксисе оболочки такого оператора нет.
 – 
Kusalananda
21 Май 2018 в 15:30
Ой! Я имел в виду, что это похоже на оператор конкатенации, а не на самом деле оператор.
 – 
Bhagyesh Dudhediya
21 Май 2018 в 19:16