У меня есть плагин, который генерирует и копирует в буфер обмена готовую к вставке команду, которая затем создает файл, который я хочу переместить и переименовать с помощью пользовательского ввода.
Если я использую это для получения последнего измененного файла в каталоге, то файл будет правильно скопирован и переименован, как указано в сценарии:
#!/bin/bash
gnome-terminal --tab-with-profile=PROFILENAME --working-directory="/PATH/WAY" -x bash -c "$(xclip -se c -o); find /PATH/WAY -type f -printf '%TY-%Tm-%Td %TT %p\n' | sort -r | head -n1 | grep -o "/home.*" | xargs -I '{}' cp '{}' /PATH/TO/Desktop/test.txt; read -p 'Press Enter to close.'"
Однако, если я попытаюсь добавить пользовательский ввод таким образом, переменная, кажется, не установлена:
gnome-terminal --tab-with-profile=PROFILENAME --working-directory="/PATH/WAY" -x bash -c "$(xclip -se c -o); echo File name?; read newfile; echo File will be named $newfile.txt; find /PATH/WAY -type f -printf '%TY-%Tm-%Td %TT %p\n' | sort -r | head -n1 | grep -o "/PATH.*" | xargs -I '{}' cp '{}' /PATH/TO/Desktop/$newfile.flv; read -p 'Press Enter to close.'"
Поскольку вывод говорит File will be named .txt
, а я ожидаю File will be named USERINPUT.txt
, а файл не копируется.
Интересно, что если я использую эти команды в скрипте bash, как это, то все работает нормально:
#!/bin/bash
echo File name?
read newfile
echo File will be named $newfile.txt
find /PATH/WAY -type f -printf '%TY-%Tm-%Td %TT %p\n' | sort -r | head -n1 | grep -o "/PATH.*" | xargs -I '{}' cp '{}' /PATH/TO/Desktop/$newfile.txt
read -p 'Press Enter to close.'
Я не понимаю, что я делаю неправильно ...
Один большой параметр после bash -c
находится в двойных кавычках. Это означает, что подстановка определенных вещей (включая $newfile
) выполняется здесь самой внешней оболочкой, то есть оболочкой, которая собирается запустить gnome-терминал перед его запуском. В этом контексте эта переменная не определена.
Я рекомендую вам использовать отдельный скрипт, как показано в нижней части вашего поста. Однострочники ужасно нечитаемы в любом случае.
Другие возможности включают замену кавычек '
и "
в командной строке, так что '
является внешней (то есть $newline
остается $newline
и не заменяется внешней оболочкой, это позже интерпретируется тем, что был запущен gnome-терминал); или избегая знака $
в $newfile
как \$newfile
.
И пока мы на этом:
$(xsel ...)
выполняет содержимое буфера обмена как команду (или серию команд) без какой-либо проверки. Например. если в вашем буфере обмена есть строка rm -rf ~
, ваш домашний каталог упал. Я не уверен, каково ваше намерение, но для вашей безопасности вы должны отказаться от этого подхода и найти другое решение!
echo File name?
выполняет сопоставление с шаблоном оболочки для файлов, имена которых состоят из пяти символов: name
а затем один произвольный символ. Используйте пару одинарных или двойных кавычек.
Вы ссылаетесь на имя переменной $newfile
без кавычек. Это приведет к ошибочному поведению, если оно содержит пробелы. Вместо этого обращайтесь к нему как "$newfile"
.