简体   繁体   English

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

[英]bash: How to assign script name to a variable and call it from another script

I have a simple bash script that works correctly on its own, and a second script, that at some point should call the first script and execute it. 我有一个简单的bash脚本可以自己正常工作,还有第二个脚本,它在某些时候应该调用第一个脚本并执行它。 In the second script, I assign the first script's name into a variable and then try to call it with: sh ${VARIABLE} 在第二个脚本中,我将第一个脚本的名称分配给变量,然后尝试使用以下命令调用它: sh ${VARIABLE}

The problem I face is: 我面临的问题是:
while ${VARIABLE} correctly stores the name of the script, the line sh ${VARIABLE} returns an empty value, thus does not execute the script. 虽然${VARIABLE}正确存储了脚本的名称,但行sh ${VARIABLE}返回一个空值,因此不执行脚本。

Relevant part of the code: 代码的相关部分:

#!/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}
}

The commented out echo, I included them in an attempt to troubleshot. 被评论的回声,我把他们包括在试图麻烦。 When I uncomment them, the first three return the expected values, while the 4th returns empty line: 当我取消注释它们时,前三个返回预期值,而第四个返回空行:

# 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)

When I run my script, I get a No such file or directory error. 当我运行我的脚本时,我得到一个No such file or directory错误。

I have been googling for answers and searched in Stackoverflow as well, but I think I am not using the correct search terms, because I get answers about how to pass variable values or arguments from one script to another. 我一直在谷歌上搜索答案并在Stackoverflow中搜索,但我认为我没有使用正确的搜索术语,因为我得到了关于如何将变量值或参数从一个脚本传递到另一个脚本的答案。

I have been trying to resolve this for hours, with set -x; trap read debug 我一直试图解决这个问题几个小时,使用set -x; trap read debug set -x; trap read debug and putting echo everywhere to make sure all my variables and paths are correct. set -x; trap read debug并在任何地方放置回声以确保我的所有变量和路径都是正确的。

I've trying adding quotes around my variable, removing quotes and curly brackets and explicitly assign the variable name: even then, the script called returns empty. 我试图在我的变量周围添加引号,删除引号和大括号并显式分配变量名称:即使这样,调用的脚本返回空。

The script that I call starts with #!/bin/bash (absolutely no ^M or ^r or any Windows style newlines or symbols) and in my pc /bin/sh is a soft link to /bin/bash . 我调用的脚本以#!/bin/bash (绝对没有^M^r或任何Windows样式的换行符或符号)开头,而在我的pc /bin/sh则是/bin/bash的软链接。 Still, I tried calling the second script with /bin/bash instead of sh , which made no difference. 不过,我尝试使用/bin/bash而不是sh调用第二个脚本,这没有任何区别。

Also, since my script requires switch user, I made sure that all the variables are listed in the script when it's called. 此外,由于我的脚本需要切换用户,因此我确保在调用脚本时列出所有变量。

If I pass all the variables and the function directly on the shell, and then call it comp , it executes correctly the second script. 如果我直接在shell上传递所有变量和函数,然后调用它comp ,它会正确执行第二个脚本。

I am pretty sure I am doing a typical newbie mistake here, and I would really appreciate any insight. 我很确定我在这里做了一个典型的新手错误,我真的很感激任何见解。 Sorry for being so verbose, I didn't know how much detail to include. 很抱歉这么详细,我不知道要包含多少细节。


Updated : 更新

@shellter comments: @shellter评论:

ls -l -- "$PRGSCRIPT" gives ls: cannot access 20151013-b4-1510.sh: No such file or directory , while echo $PRGSCRIPT returns the name of the file correctly. ls -l -- "$PRGSCRIPT"ls: cannot access 20151013-b4-1510.sh: No such file or directory ,而echo $PRGSCRIPT正确返回文件的名称。

I did not include all of the script, the first part sets all the variables, ( ${THISCWD} , ${THISPRG} etc). 我没有包含所有脚本,第一部分设置所有变量,( ${THISCWD}${THISPRG}等)。 Also when I do the test echo $(pwd) it shows that I am in the correct path. 此外,当我进行测试echo $(pwd)它表明我在正确的路径中。 I am getting more and more confused... 我变得越来越困惑......

Also Windows editing was not involved in any part of the process, I used vi in Linux for both scripts and only in my local machine, no ftp involved. Windows编辑也没有涉及到该过程的任何部分,我在Linux中使用vi作为两个脚本,并且仅在我的本地机器中使用,不涉及ftp。 No spaces in the path either. 路径中也没有空格。

Regarding relevant mount output: I am not sure what you mean. 关于相关的安装输出:我不确定你的意思。 The root partition is in /dev/sda1 and my home partition in /dev/sda5 . 根分区位于/dev/sda1而我的主分区位于/dev/sda5 My $PATH correctly sees /bin , /usr/bin , etc 我的$PATH正确地看到/bin/usr/bin

Thanks for your time - I am updating the question as you suggested, to avoid long comment list 感谢您的时间 - 我正在按照您的建议更新问题,以避免长评论列表

More updates, in response to comments : 更多更新,以回应评论

@ shellter @ shellter

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

I will make sure to double-check the permissions in the script folder (great script, btw :) - hope you don't mind that I will be using it!) however, since I actually su before running the script, I think it won't be a permissions problem 我将确保仔细检查脚本文件夹中的权限(伟大的脚本,顺便说一句:) - 希望你不介意我将使用它!)但是,因为我在运行脚本之前实际上是su ,我认为它不会是权限问题

@couling @couling

I did find a problem in this! 我确实发现了这个问题! I tested the outputs, as you suggested, in ht and got a non-printable character in every end of line: 我按照你的建议在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###?      |

All my lines end with an 0a character... Same in the ls.txt file. 我的所有行都以0a字符结尾...在ls.txt文件中相同。 I have no idea how to fix this, any suggestions? 我不知道如何解决这个问题,有什么建议吗? Didn't think that vi and vim would add new line characters. 没想到vivim会添加新的行字符。

updated ls.txt 更新了 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|  

Part of the output: I also have the 0a characters here. 部分输出:我在这里也有0个字符。 I checked all the characters shown as ? 我检查了显示的所有字符? and they all are 0a 他们都是0a

updated 更新

In the end, I copied most parts of the script minus comments and echo in a new file and now, for some reason, it works as expected... 最后,我复制脚本减去意见和大部分地区echo在一个新的文件,而现在,出于某种原因,它按预期工作...

I still have no idea what happened or what was my problem. 我仍然不知道发生了什么或者我的问题是什么。

I thank you all very much for your assistance, I've learned a few things in the process. 我非常感谢你的帮助,我在这个过程中学到了一些东西。 I much appreciate you all taking the time to help me out. 我非常感谢你们花时间帮助我。

It is very hard to give a definitive answer on this but it looks like there is a non-printable character getting in there somewhere. 很难给出一个明确的答案,但看起来有一个不可打印的角色进入某个地方。 By non-printable I'm referring to \\r and other characters. 通过不可打印我指的是\\r和其他字符。 I know you've stated that there is no \\r in the variable. 我知道你已经声明变量中没有\\r

This could be either in the variable or the file name. 这可以是变量或文件名。

I'd do an ls -l > ls.txt and run your script to echo "###${PRGSCRIPT}###" > prgscript.txt . 我会做一个ls -l > ls.txt并运行你的脚本echo "###${PRGSCRIPT}###" > prgscript.txt I'd then find a decent hex editor to analyse the result (one which shows the askii along side the hex). 然后我会找到一个合适的十六进制编辑器来分析结果(一个显示在hex的旁边的askii)。 From what you've posted here I'd expect to see a discrepancy somewhere in the output (quite possibly involving a non-printable character). 根据你在这里发布的内容,我希望在输出中的某个地方看到一个差异(很可能涉及一个不可打印的字符)。

Pay extra attention to new line characters before the trailing ### in the variable echo. 在变量echo中跟踪###之前要特别注意新行字符。

Without your full environment I have to follow couling's comment about how hard it is to give a definitive answer. 如果没有完整的环境,我必须遵循couling的评论,即给出明确的答案有多难。 But I spot a cd embedded in your script so some tips from years of scripting follow: 但我发现你的脚本中嵌入了一个cd ,因此多年脚本编写的一些提示如下:

  • Always resolve $0 to absolute path names, especially if your script uses cd commands. 始终将$ 0解析为绝对路径名,尤其是在脚本使用cd命令的情况下。
     pwd0="$PWD"; pwd0 = “$ PWD”;\nname0="$0"; NAME0 = “$ 0”;\nif [[ "$name0" != /* ]]; if [[“$ name0”!= / *]]; then name0="$pwd0/$name0"; 然后name0 =“$ pwd0 / $ name0”; fi; 网络连接;\n$name0-1510; $ name0-1510; #assure execute matching "1510" program IN SAME DIRECTORY #assure在同一目录中执行匹配“1510”程序 
    This is very important if you want to execute other scripts in the same directory, which does not appear in PATH (ignoring ".", which cd commands invalidate). 如果要在同一目录中执行其他脚本(这不会出现在PATH中)(忽略“。”,哪些cd命令无效),这一点非常重要。 This copes with assorted strange games that can be played with PATH and absolute paths to scripts across behaviors of different operating systems and shells. 这可以应对各种奇怪的游戏,可以使用PATH和跨越不同操作系统和shell的行为的脚本的绝对路径。
  • On key variables you are having trouble with use the :? 关键变量你在使用时遇到问题:? notation to fail with error if a variable is not well defined: 如果变量定义不明确,则表示失败并出现错误:
     PRGSCRIPT="${THISPRG:?"$LINENO: THISPRG not defined"}-1510.sh" PRGSCRIPT =“$ {THISPRG:?”$ LINENO:THISPRG未定义“}  -  1510.sh” 
    Admittedly this is not your current problem, but a good idea at key points. 不可否认,这不是你目前的问题,而是关键点的好主意。

First, check the status code after the cd , to see whether it worked. 首先,检查cd后的状态代码,看它是否有效。

Second, you write that you verified that PRGSCRIPT has the value 20151013-b4-1510.sh . 其次,你写你验证PRGSCRIPT具有价值20151013-b4-1510.sh Now we have three possibilities: 现在我们有三种可能性:

  1. Either the shell finds a readable file of this name, in which case it will execute it somehow (and if you want to know what's going on inside this file, you can switch on a trace using the -x switch), or shell可以找到这个名称的可读文件,在这种情况下它会以某种方式执行它(如果你想知道这个文件里面发生了什么,你可以使用-x开关打开一个跟踪),或者

  2. The shell will output an error message shell将输出错误消息

In theory, we also have the case that the file contains no executable commands (only comment lines), but this is something you can investigate separately. 理论上,我们还有一个案例,即文件不包含可执行命令(只有注释行),但您可以单独调查。

For example, doing a 例如,做一个

cat $PRGSCRIPT
sh -x $PRGSCRIPT

should reveal what's going on (unless you have redirected stdout and stderr of the calling script to the bit bucket). 应该揭示发生了什么(除非你已经将调用脚本的stdout和stderr重定向到位桶)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM