bash:如何将脚本名称分配给变量并从另一个脚本

时间:2015-10-24 12:29:00

标签: bash shell

我有一个简单的bash脚本可以自己正常工作,还有第二个脚本,在某些时候应该调用第一个脚本并执行它。 在第二个脚本中,我将第一个脚本的名称分配给变量,然后尝试使用以下命令调用它:sh ${VARIABLE}

我面临的问题是:
虽然${VARIABLE}正确存储了脚本的名称,但行sh ${VARIABLE}返回一个空值,因此不执行脚本。

代码的相关部分:

#!/bin/bash

comp(){
    # Check if user is root
    if [ ! $(whoami) == "root" ]; then
        echo "Need root!"
        exit 1
    fi
    export make="make -j4"
    cd ${THISCWD}/${THISPRG}/${SRCDIR}/
    PRGSCRIPT="${THISPRG}-1510.sh"
# echo $(pwd)
# echo $PRGSCRIPT
# echo $(ls | grep "20151013-b4-1510.sh")
# echo $(ls | grep "${PRGSCRIPT}")
    sh ${PRGSCRIPT}
}

评论的回声,我把它们包括在试图麻烦中。当我取消注释它们时,前三个返回预期值,而第四个返回空行:

# echo $PRGSCRIPT
20151013-b4-1510.sh
# echo $(ls | grep "20151013-b4-1510.sh")
20151013-b4-1510.sh
# echo $(ls | grep "${PRGSCRIPT}")
   # (<- I get an empty line here)

当我运行脚本时,出现No such file or directory错误。

我一直在谷歌上搜索答案并在Stackoverflow中搜索,但我认为我没有使用正确的搜索术语,因为我得到了关于如何将变量值或参数从一个脚本传递到另一个脚本的答案。

我一直试图用set -x; trap read debug解决这个问题,并在每个地方都设置回声以确保我的所有变量和路径都是正确的。

我正在尝试在变量周围添加引号,删除引号和大括号并显式指定变量名称:即使这样,调用的脚本也会返回空。

我调用的脚本以#!/bin/bash开头(绝对没有^M^r或任何Windows风格的换行符或符号),在我的电脑/bin/sh中是一个软链接到/bin/bash。不过,我尝试使用/bin/bash而不是sh来调用第二个脚本,这没有任何区别。

此外,由于我的脚本需要切换用户,因此我确保在调用脚本时列出所有变量。

如果我直接在shell上传递所有变量和函数,然后调用它comp,它就会正确执行第二个脚本。

我很确定我在这里做了一个典型的新手错误,我真的很感激任何见解。很抱歉这么详细,我不知道要包括多少细节。

更新

@shellter评论:

ls -l -- "$PRGSCRIPT"提供ls: cannot access 20151013-b4-1510.sh: No such file or directory,而echo $PRGSCRIPT正确返回文件名。

我没有包含所有脚本,第一部分设置了所有变量,(${THISCWD}${THISPRG}等)。此外,当我进行测试echo $(pwd)时,它表明我处于正确的路径中。我变得越来越困惑......

此过程的任何部分都没有涉及Windows编辑,我在Linux中使用vi作为两个脚本,并且仅在本地计算机中使用,不涉及ftp。路径中也没有空格。

关于相关的mount输出: 我不确定你的意思。根分区位于/dev/sda1,我的主分区位于/dev/sda5。我的$PATH正确看到/bin/usr/bin

感谢您的时间 - 我正在按照您的建议更新问题,以避免长评论列表

更多更新,以回应评论

@ shellter

# mount | egrep 'sda1|sda5'
/dev/sda1 on / type ext4 (rw)
/dev/sda5 on /home type ext4 (rw)

我将确保仔细检查脚本文件夹中的权限(伟大的脚本,顺便说一句:) - 希望你不介意我将使用它!)但是,因为我实际上su之前运行脚本,我认为这不会是权限问题

@couling

我确实发现了这个问题!我按照你的建议在ht测试了输出,并且在每一行都有一个不可打印的字符:

│00000000 23 23 23 32 30 31 35 31-30 31 33 2d 62 34 2d 31 |###20151013-b4-1|                             │
│00000010 35 31 30 2e 73 68 23 23-23 0a                   |510.sh###?      |

我的所有行都以0a字符结尾...在ls.txt文件中相同。我不知道如何解决这个问题,有什么建议吗?不要以为vivim会添加换行符。

更新 ls.txt

│00000000 74 6f 74 61 6c 20 36 34-0a 64 72 77 78 72 2d 78 |total 64?drwxr-x|                             ^
│00000010 72 2d 78 20 32 20 62 34-74 73 74 73 20 75 73 65 |r-x 2 b4tsts use|                             ▒
│00000020 72 73 20 34 30 39 36 20-4f 63 74 20 31 31 20 30 |rs 4096 Oct 11 0|                             ▒
│00000030 38 3a 30 32 20 32 30 31-35 31 30 30 31 0a 64 72 |8:02 20151001?dr|                             ▒
│00000040 77 78 72 2d 78 72 2d 78-20 32 20 62 34 74 73 74 |wxr-xr-x 2 b4tst|                             ▒
│00000050 73 20 75 73 65 72 73 20-34 30 39 36 20 4f 63 74 |s users 4096 Oct|                             ▒
│00000060 20 31 31 20 30 38 3a 30-32 20 32 30 31 35 31 30 | 11 08:02 201510|                             ▒
│00000070 30 32 0a 64 72 77 78 72-2d 78 72 2d 78 20 32 20 |02?drwxr-xr-x 2 |                             ▒
│00000080 62 34 74 73 74 73 20 75-73 65 72 73 20 34 30 39 |b4tsts users 409|                             ▒
│00000090 36 20 4f 63 74 20 31 31-20 30 38 3a 30 32 20 32 |6 Oct 11 08:02 2|                             ▒
│000000a0 30 31 35 31 30 30 33 0a-64 72 77 78 72 2d 78 72 |0151003?drwxr-xr|                             ▒
│000000b0 2d 78 20 32 20 62 34 74-73 74 73 20 75 73 65 72 |-x 2 b4tsts user|                             ▒
│000000c0 73 20 34 30 39 36 20 4f-63 74 20 31 31 20 30 38 |s 4096 Oct 11 08|                             ▒
│000000d0 3a 30 34 20 32 30 31 35-31 30 30 34 0a 64 72 77 |:04 20151004?drw|                             ▒
│000000e0 78 72 2d 78 72 2d 78 20-32 20 62 34 74 73 74 73 |xr-xr-x 2 b4tsts|                             ▒
│000000f0 20 75 73 65 72 73 20 34-30 39 36 20 4f 63 74 20 | users 4096 Oct |                             ▒
│00000100 31 31 20 30 37 3a 33 31-20 32 30 31 35 31 30 30 |11 07:31 2015100|                             ▒
│00000110 35 0a 64 72 77 78 72 2d-78 72 2d 78 20 32 20 62 |5?drwxr-xr-x 2 b|                             ▒
│00000120 34 74 73 74 73 20 75 73-65 72 73 20 34 30 39 36 |4tsts users 4096|                             ▒
│00000130 20 4f 63 74 20 31 36 20-32 32 3a 33 34 20 32 30 | Oct 16 22:34 20|                             ▒
│00000140 31 35 31 30 30 36 0a 64-72 77 78 72 2d 78 72 2d |151006?drwxr-xr-|                             ▒
│00000150 78 20 32 20 62 34 74 73-74 73 20 75 73 65 72 73 |x 2 b4tsts users|                             ▒
│00000160 20 34 30 39 36 20 4f 63-74 20 31 36 20 32 32 3a | 4096 Oct 16 22:|                             ▒
│00000170 33 34 20 32 30 31 35 31-30 30 37 0a 64 72 77 78 |34 20151007?drwx|                             ▒
│00000180 72 2d 78 72 2d 78 20 32-20 62 34 74 73 74 73 20 |r-xr-x 2 b4tsts |                             ▒
│00000190 75 73 65 72 73 20 34 30-39 36 20 4f 63 74 20 31 |users 4096 Oct 1|                             ▒
│000001a0 36 20 32 32 3a 33 34 20-32 30 31 35 31 30 30 38 |6 22:34 20151008|  

部分输出:我这里也有0个字符。我检查了显示的所有字符?它们都是0a

更新

最后,我将脚本的大部分内容减去评论并将echo复制到一个新文件中,现在由于某种原因,它按预期工作...

我仍然不知道发生了什么或我的问题是什么。

我非常感谢你的帮助,我在这个过程中学到了一些东西。我非常感谢你们抽出时间帮助我。

3 个答案:

答案 0 :(得分:1)

很难给出一个确定的答案,但看起来有一个不可打印的角色进入某处。通过不可打印,我指的是\r和其他字符。我知道你已经声明变量中没有\r

这可以是变量或文件名。

我会执行ls -l > ls.txt并将您的脚本运行到echo "###${PRGSCRIPT}###" > prgscript.txt。然后我会找到一个合适的十六进制编辑器来分析结果(一个显示在hex的旁边的askii)。根据你在这里发布的内容,我希望在输出中的某处看到差异(很可能涉及不可打印的字符)。

在变量echo中跟踪###之前,要特别注意换行符号。

答案 1 :(得分:1)

如果没有完整的环境,我必须遵循couling对于给出明确答案有多难的评论。但我发现你的脚本中嵌入了一个 cd ,所以来自多年脚本的一些提示如下:

  • 始终将$ 0解析为绝对路径名,尤其是当您的脚本使用 cd 命令时。
    pwd0="$PWD";
    name0="$0";
    if [[ "$name0" != /* ]]; then name0="$pwd0/$name0"; fi;
    $name0-1510;  #assure execute matching "1510" program IN SAME DIRECTORY
    如果要在同一目录中执行其他脚本(这不会出现在PATH中)(忽略“。”, cd 命令无效),这一点非常重要。这可以应对各种奇怪的游戏,可以使用PATH和不同操作系统和shell的行为的脚本绝对路径。
  • 关键变量使用时遇到问题:?如果变量定义不明确,则表示失败并出现错误:
    PRGSCRIPT="${THISPRG:?"$LINENO: THISPRG not defined"}-1510.sh"
    不可否认,这不是你目前的问题,而是关键点的好主意。

答案 2 :(得分:0)

首先,检查cd后的状态代码,看它是否有效。

其次,您写道,您确认PRGSCRIPT的值为20151013-b4-1510.sh。现在我们有三种可能性:

  1. shell找到一个这个名称的可读文件,在这种情况下它会以某种方式执行它(如果你想知道这个文件里面发生了什么,你可以使用它来打开一个跟踪-x开关)或

  2. shell将输出错误消息

  3. 理论上,我们还有一个案例,即该文件不包含可执行命令(只有注释行),但您可以单独调查这些内容。

    例如,做一个

    cat $PRGSCRIPT
    sh -x $PRGSCRIPT
    

    应该显示正在进行的操作(除非您已将调用脚本的stdout和stderr重定向到位桶)。