如何从脚本更改目录而不使用 . ./script,或者调用 ./script 时退出脚本。 ./脚本.sh

如何从脚本更改目录而不使用 . ./script,或者调用 ./script 时退出脚本。 ./脚本.sh

我有一个 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.shexit 按预期工作,但目录更改为脚本子 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,因此退出会话是正常的。

相关内容