Вопрос или проблема
Я использую Cygwin в качестве замены командной строки в Windows и сейчас занимаюсь очисткой переменной PATH системы.
У меня есть папка, содержащая exe и ярлыки (.LNK), которая находится в PATH и содержит все небольшие приложения и программы, которыми я пользуюсь из командной строки.
Все работает через CMD, однако ярлыки, файлы .LNK, не работают через Cygwin.
Вместо этого я получаю
bash: /cygdrive/e/Apps/uniserver.lnk: не удается выполнить двоичный файл
Мое единственное предположение – это потому, что он считает .lnk символической ссылкой?
Есть ли способ запустить ярлык через Cygwin?
Вы можете выполнять файлы Windows LNK из Cygwin, используя утилиту cygstart
, которая является частью пакета cygutils, следующим образом:
cygstart [OPTION]... FILE [ARGUMENTS]
Смотрите cygstart --help
для доступных опций.
Следующее должно быть достаточно для вашего случая:
cygstart /cygdrive/e/Apps/uniserver.lnk
Я сделал аналогичную настройку и задавался вопросом, могу ли я сэкономить время, не вводя суффикс .lnk
каждый раз. Попробовал хук command_not_found_handle
, добавленный начиная с Bash 4.0, и, похоже, это работает:
# добавьте это в ваш .bashrc
command_not_found_handle ()
{
if [[ $1 == *.* || $1 == */* ]]; then
echo "$1: команда не найдена"
return 127
fi
local binbase=/cygdrive/e/Apps/
local name=$1
shift
# Возможно, вы захотите изменить порядок
if [[ -f ./$name.bat ]]; then
exec "./$name.bat" "$@"
elif [[ -f ./$name.lnk ]]; then
exec cygstart "./$name.lnk" "$@"
elif [[ -f $binbase/$name.bat ]]; then
exec "$binbase/$name.bat" "$@"
elif [[ -f $binbase/$name.lnk ]]; then
exec cygstart "$binbase/$name.lnk" "$@"
else
echo "$name: команда не найдена"
return 127
fi
}
Например, ввод лишь uniserver
вызывает этот хук и находит /cygdrive/e/Apps/uniserver.lnk
для запуска.
Редактировать: Альтернатива, которая ищет по всему $PATH
для ярлыков.
command_not_found_handle ()
{
if [[ $1 == *.* || $1 == */* ]]
then
echo "$1: команда не найдена"
return 127
fi
local name=$1
shift
if [[ -f ./$name.bat ]]
then
exec "./$name.bat" "$@"
elif [[ -f ./$name.lnk ]]
then
exec cygstart "./$name.lnk" "$@"
elif [[ -f $(type -P $name.bat) ]]
then
exec "$(type -P $name.bat)" "$@"
elif [[ -f $(type -P $name.lnk) ]]
then
exec cygstart "$(type -P $name.lnk)" "$@"
else
echo "$name: команда не найдена"
return 127
fi
}
Используйте встроенную команду DOS start
. Думаю, Cygwin не имеет доступа к встроенным командам DOS, поэтому вам придется написать обертку, например mystart.bat, и запускать ваши LNK’и через этот скрипт.
Не думаю, что вы можете “ассоциировать” файлы LNK в Cygwin, чтобы автоматически запускать вашу обертку, но, возможно, кто-то другой подскажет, как это сделать.
Ответ или решение
Исполнение файлов ярлыков (.LNK) в Cygwin: Подробное руководство
Cygwin — это мощная среда для Windows, позволяющая использовать командную строку Unix и одновременно предоставляющая доступ к различным инструментам Linux. Несмотря на свои многие преимущества, многие пользователи сталкиваются с проблемой выполнения файлов ярлыков (.LNK) с помощью Cygwin. Эта статья поможет вам понять, как эффективно запускать такие файлы, используя утилиту cygstart
, а также предложит дополнительные усовершенствования.
Проблема и её решение
Как вы заметили, при попытке запустить файл ярлыка (.LNK) в Cygwin, система выдает сообщение:
bash: /cygdrive/e/Apps/uniserver.lnk: cannot execute binary file
Это связано с тем, что Cygwin не воспринимает .LNK файлы как исполняемые бинарные файлы. Вместо этого он интерпретирует их как обычные файлы, что и приводит к ошибке. Чтобы обойти эту проблему, можно использовать утилиту cygstart
, которая предназначена для запуска файлов и программ в среде Windows напрямую из Cygwin.
Использование утилиты cygstart
cygstart
предоставляется в пакете cygutils и позволяет запускать Windows приложения, включая ярлыки .LNK. Чтобы запустить файл ярлыка с помощью cygstart
, используйте следующий синтаксис:
cygstart /cygdrive/e/Apps/uniserver.lnk
Эта команда запускает указанный ярлык в Windows, что позволяет избежать проблем с совместимостью.
Автоматизация процесса выполнения .LNK файлов
Если вы хотите упростить процесс и избежать необходимости каждый раз вводить .lnk
, можно использовать хук command_not_found_handle
в вашем .bashrc
файле. Убедитесь, что вы добавили следующий код в ваш .bashrc
:
command_not_found_handle() {
if [[ $1 == *.* || $1 == */* ]]; then
echo "$1: команда не найдена"
return 127
fi
local binbase=/cygdrive/e/Apps/
local name=$1
shift
if [[ -f ./$name.bat ]]; then
exec "./$name.bat" "$@"
elif [[ -f ./$name.lnk ]]; then
exec cygstart "./$name.lnk" "$@"
elif [[ -f $binbase/$name.bat ]]; then
exec "$binbase/$name.bat" "$@"
elif [[ -f $binbase/$name.lnk ]]; then
exec cygstart "$binbase/$name.lnk" "$@"
else
echo "$name: команда не найдена"
return 127
fi
}
С этой настройкой теперь вы сможете просто вводить имя ярлыка, например, uniserver
, без необходимости добавлять .lnk
каждый раз.
Альтернативный подход: Обработка всей переменной $PATH
Если вы хотите, чтобы система автоматически искала ярлыки (.LNK) в каталогах, указанных в переменной среды $PATH
, вы можете изменить код следующего образом:
command_not_found_handle() {
if [[ $1 == *.* || $1 == */* ]]; then
echo "$1: команда не найдена"
return 127
fi
local name=$1
shift
if [[ -f ./$name.bat ]]; then
exec "./$name.bat" "$@"
elif [[ -f ./$name.lnk ]]; then
exec cygstart "./$name.lnk" "$@"
elif [[ -f $(type -P $name.bat) ]]; then
exec "$(type -P $name.bat)" "$@"
elif [[ -f $(type -P $name.lnk) ]]; then
exec cygstart "$(type -P $name.lnk)" "$@"
else
echo "$name: команда не найдена"
return 127
fi
}
Эта версия будет искать исполняемые файлы в текущем каталоге и в каталогах, указанных в $PATH
.
Заключение
Использование утилиты cygstart
и настройка хука command_not_found_handle
позволяют эффективно интегрировать выполнение .LNK файлов в вашу повседневную работу с Cygwin. Теперь вы способны минимизировать количество вводимой информации и максимально упростить процесс запуска приложений через командную строку, что делает вашу работу более удобной и эффективной.