【问题标题】:script full name and path $0 not visible when called调用时脚本全名和路径 $0 不可见
【发布时间】:2018-09-05 17:15:06
【问题描述】:

我有一个脚本“task.sh”,内容如下:

#!/bin/bash

CUR_DIR=`pwd`
SCRIPTPATH="${CUR_DIR}/`dirname $0`"

当我用“bash task.sh”调用它时,它按预期工作,但是当它用“.task.sh”调用时

$ . log/task.sh 
dirname: invalid option -- b
Try `dirname --help' for more information.

当脚本在 crontab 中调度时,它不能正常工作。 有人可以告诉我我做错了什么或以不同的方式来获取不是当前目录的脚本目录 ?

【问题讨论】:

  • 快速猜测一下:试试SCRIPTPATH="${CUR_DIR}/`dirname "$0"`",即引用$0。除此之外,CUR_DIR 在这里似乎是多余的。

标签: bash shell argv


【解决方案1】:

当您以bash task.sh 调用它时,bash 将“task.sh”分配给 $0(来自bash manual:“如果使用命令文件调用 Bash [...] $0 设置为那个文件。”)。

当您获取文件时,bash 不会更改 $0,它只是在当前环境中执行脚本。在您当前的环境中,0 美元是什么?

$ echo "$0"
-bash

dirname 将把前面的破折号解释为一个选项。

如果是 cron 任务,为什么要采购它?

如果您需要获取脚本,如果您的 shell 是 bash,这将起作用:

SCRIPTPATH="${CUR_DIR}/${BASH_ARGV[0]}"

但是,我相信 cron 的 shell 是 /bin/sh。即使 /bin/sh 是 bash 的符号链接,当 bash 作为 sh 调用时,它也会尝试表现 POSIXly:BASH_ARGV 数组可能对您不可用。

【讨论】:

  • 这样写,现在完美运行:) CUR_DIR="$PWD" SCRIPTFILE=$0 if [ "${SCRIPTFILE}" = "-bash" ] ; then SCRIPTFILE=${BASH_ARGV[0]} fi SCRIPTPATH="${CUR_DIR}/dirname ${SCRIPTFILE}"
【解决方案2】:

使用 bash 时没有理由调用外部二进制文件,例如 pwddirname。这两个二进制文件的功能可以用纯 shell 语法复制。

尝试以下方法:

#!/bin/bash

CUR_DIR="$PWD"
SCRIPTPATH="${CUR_DIR}/${0#*/}"

【讨论】:

  • 这要求您在运行时与脚本位于同一目录中...不理想。
【解决方案3】:

当你输入时,

bash foo.sh

您正在执行脚本 foo.sh,并且 bash 将输入参数 $0 设置为正在运行的脚本的名称。

当你输入时,

. foo.sh

您正在获取脚本并且未设置输入参数 $0。 在这种情况下,您可以使用包含最后执行命令的参数的自动变量 $_。 在您的脚本中,您可以键入,

SCRIPTPATH=$(dirname "$_")

获取 foo.sh 的路径。 请注意,要使其正常工作,这必须是文件中执行的第一个命令。 否则 $_ 将不包含源脚本的路径。

感谢Dennis Williamson 为类似的question 提供此答案。

【讨论】:

    【解决方案4】:

    我已经用了很长时间了。

    SCRIPTPATH=$(cd `dirname -- $0` && pwd)
    

    -- 禁止进一步处理参数。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-09-21
      • 1970-01-01
      • 2013-10-17
      • 1970-01-01
      • 1970-01-01
      • 2021-03-24
      • 1970-01-01
      • 2014-10-03
      相关资源
      最近更新 更多