Я использую этот прием:
options=("First option" "Second option" "Quit")
PS3="So what? "
select opt in "${options[@]}"
do
case $opt in
"First option")
echo "First option"
;;
"Second option")
echo "Second option"
;;
"Quit")
echo "We are done..."
break
;;
*)
PS3="" # this hides the prompt
echo asdf | select foo in "${options[@]}"; do break; done # dummy select
PS3="So what? " # this displays the common prompt
;;
esac
done
Проблема не связана с символической ссылкой.
Если mycommand.sh
вызывает ./mycommand2.sh
, он ожидает, что его текущий рабочий каталог будет somedir
.Текущий рабочий каталог не связан с тем, как команда была названа или вызвана. Это свойство процессов, которое задается системным вызовом chdir()
или встроенной командой cd
в оболочках.
Если бы вы это сделали:
cd /path/to/somedir
mycommand
mycommand
, он же mycommand.sh
, все равно найдет ./mycommand2.sh
в текущем каталоге.
Чтобы mycommand.sh
находил mycommand2.sh
независимо от рабочего каталога, из которого он вызывается, его необходимо изменить, например:
#! /bin/sh -
mydir=$(dirname -- "$0")
"${mydir%/}/mycommand2.sh"
Или, если mycommand.sh
требует, чтобы его рабочий каталог былsomedir
:
#! /bin/sh -
mydir=$(dirname -- "$0")
CDPATH= cd -P -- "$mydir" || exit
./mycommand2.sh
И это при использовании символической ссылки может вызвать проблемы, как если бы mycommand
, dirname -- "$0"
вернуло бы имя каталога символической ссылки mycommand
, а не скрипта mycommand.sh
.
Чтобы обойти это, вы должны изменить mycommand.sh
как:
#! /bin/sh -
mydir=$(dirname -- "$(readlink -f -- "$0")")
"${mydir%/}/mycommand2.sh"
Гдеreadlink -f
(не стандартная команда, а довольно распространенная )разрешит все символические ссылки. Это предполагает, что mycommand.sh
сам по себе не является символической ссылкой на скрипт в другом каталоге.
Если вы не можете или не хотите изменять этот скрипт, другим подходом может быть созданиеmycommand
скрипта вместо символической ссылки , который выполняет:
#! /bin/sh -
cd /path/to/somedir &&
exec./mycommand.sh "$@"