我有一个 bash 脚本,它将调用该脚本的用户移动到新的工作目录。
如果我使用 cd 调用脚本. ./script.sh
,则用户会移动到新目录,但问题是如果没有参数传递给脚本,脚本也会使用 exit 命令,这会导致用户的 SSH 会话关闭。
如何在不调用脚本的情况下更改目录. ./script.sh
,或者如何在调用时退出脚本而不终止用户会话. ./script.sh
。
我遇到问题的脚本部分是这样的:
#!/bin/bash
VAR=$1
if [[ "$VAR" == "" ]]; then printf "No argument provided, please provide what you want to check.\n"; exit 1; fi
change_cwd () {
cd $NEWDIR
}
change_cwd
如果我调用./script.sh
exit 按预期工作,但目录更改为脚本子 shell,而不是用户,但如果我使用,. ./script.sh
则 exit 会杀死调用脚本的用户的整个 SSH 会话。
解决这个问题的方法是什么,让 exit 和 cd 都可以从 bash 脚本工作,以其他方式更改目录或以其他方式退出脚本?
关键是我需要让脚本更改用户的工作目录,并且在没有参数或参数错误的情况下,因为我打算为 $VAR 添加一些其他检查,请停止执行脚本的其余部分并返回到用户 shell,以便用户再次运行脚本。
答案1
如果脚本被调用为./script
,则它无法更改其父进程的当前目录。因此该脚本必须作为. ./script
.
您可以使用return
内置函数退出脚本并返回到其调用者。您只能在函数外部执行此操作:在函数中,return
将从函数返回,而不是从脚本返回。
请记住,如果您的脚本是源代码,它将由用户的 shell 执行,而不是由 bash 执行,因此其他 shell(zsh、fish、tcsh 等)的用户将无法使用您的脚本。编写在 bash 和 zsh 中工作的脚本相对容易(用以下命令启动脚本,emulate -L ksh 2>/dev/null
大多数事情都会工作),但编写在 Fish 和 tcsh 中也工作的脚本则明显不那么容易。
解决 shell 不兼容性的另一种方法是在您选择的程序中编写逻辑来解析参数、确定要更改到哪个目录等。然后让您的程序打印出调用者 shell 的 shell 代码,并让调用者评估脚本的输出。因此你的脚本可能会输出类似的内容
cd /some/where
或者
echo "Error: blah blah"; false
它将被调用
eval "`./script`"
或 tcsh/fish/... 类似物。
答案2
使用 $# 测试提供的参数总数。如果 $# 为 0,则不发出 exit 命令。
我不确定 change_cwd 函数是什么样的,因为$NEWDIR
没有定义,但这里有一个可以工作的示例:
VAR=$1
ARGC=$#
if test $ARGC -eq 0
then
printf "No argument provided, please provide what you want to check.\n"
else
change_cwd ()
{
cd $NEWDIR
}
fi
(未经测试,但你明白了要点..)
test -z
另外,测试空字符串可能会更简洁。
答案3
该脚本正在关闭 ssh 会话,因为 . ./script 不会创建子 shell,而是在当前 shell 中运行脚本,因此退出此处被视为当前交互式 shell,因此退出会话是正常的。