Когда команда не найдена, статус выхода равняется 127. Вы могли использовать это, чтобы решить, что команда не была найдена:
until
printf "Enter a command: "
read command
"$command"
[ "$?" -ne 127 ]
do
echo Try again
done
В то время как команды обычно не возвращают 127 статусов выхода (для самого случая, что он конфликтовал бы с тем стандартным специальным значением, используемым оболочками), существуют некоторые случаи, куда команда может действительно возвратить 127 статусов выхода: сценарий, последняя команда которого не может быть найдена.
bash
и zsh
имейте специальное предложение command_not_found_handler
функция (существует опечатка в bash
поскольку это называют command_not_found_handle
там), который при определении выполняется, когда команда не найдена. Но это выполняется в контексте подоболочки, и это может также быть выполнено после команд, не найденных при выполнении функции.
Вы могли испытать желание проверить на существование команды заранее с помощью type
или command -v
, но остерегайтесь этого:
"$commands"
анализируется как, простые команды и псевдонимы не расширены, в то время как type
или command
возвратил бы true для псевдонимов и ключевых слов оболочки также.
Например, с command=for
, type -- "$command"
возвратил бы true, но "$command"
(по всей вероятности) возвратил бы команду, не найденную ошибкой.
which
может перестать работать по большому количеству других причин.
Идеально, Вы хотели бы что-то, что возвращает true, если команда существует или как функция, встроенная оболочка или как внешняя команда.
hash
соответствовал бы тем критериям, по крайней мере, для ash
и bash
(нет yash
ни ksh
ни zsh
). Так, это работало бы в bash
или ash
:
while
printf "Enter a command: "
read command
do
if hash -- "$command" 2> /dev/null; then
"$command"
break
fi
echo Try again
done
Одна проблема с этим - это hash
возвращает true также для каталога (для пути к каталогу включая a /
). В то время как, при попытке выполнить его, в то время как это не возвратит команду, не найденную ошибкой, это возвратит a Is a directory
или Permission Denied
ошибка. Если Вы хотите покрыть для него, Вы могли бы сделать:
while
printf "Enter a command: "
read command
do
if hash -- "$command" 2> /dev/null &&
{ [ "${command#*/}" != "$command" ] || [ ! -d "$command" ];}
then
"$command"
break
fi
echo Try again
done
Это тоже беспокоило меня в прошлом.
Решение, которое я нашел, заключалось в том, чтобы сделать Ctrl+K командой только удаления. Для меня это сработало, так как я никогда не использовал Ctrl+K для копирования и вставки.
Первоначально размещенная здесь
;; Ctrl-K with no kill
(defun delete-line-no-kill ()
(interactive)
(delete-region
(point)
(save-excursion (move-end-of-line 1) (point)))
(delete-char 1)
)
(global-set-key (kbd "C-k") 'delete-line-no-kill)
Если я правильно понимаю ваши требования, то, вероятно, самым простым решением будет вытащить (вставить) скопированное имя файла в начале мини-буфера до , выполняя обжиг в линию i. e. instead of Ctrl+a Ctrl+k, do Ctrl+a Ctrl+yCtrl+k. Вы можете заменить Ctrl+y нажатием средней кнопки мыши на вставку в той же точке, если вы предпочитаете использовать мышь.
В качестве альтернативы, в соответствии с этим ответом stackoverflow delete (NOT kill) строка в emacs должна быть возможность автоматически добавить текст, скопированный извне в emacs kill-ring, добавив
(setq save-interprogram-paste-before-kill t)
в конфигурацию emacs - это должно сделать имя файла доступным для дрожания, прокручивая его назад через убийственное кольцо с помощью Meta+y
EMACS преобразует несколько косых черт в корневой путь, например //
становится /
Если вы должны
/
Минибуфер будет иметь такой путь, как ~ // path2file / file
EMACS откроет / path2file / file
Нет необходимости переназначать Ctrl + K , просто узнайте, как EMACS обрабатывает имена файлов в минибуфере.
Прочтите раздел руководства GNU EMACS «Минибуферы для имен файлов» здесь ; начните читать с текста «Но вам не нужно убивать значение по умолчанию;»