天道酬勤,学无止境

how to declare variable name with "-" char (dash ) in linux bash script

I wrote simple script as follow

#!/bin/bash

auth_type=""

SM_Read-only="Yes"
SM_write-only="No"

echo -e  ${SM_Read-only}
echo -e  ${SM_Write-only}

if [ "${SM_Read-only}" == "Yes" ] && [ "${SM_Write-only}" == "Yes" ] 
then
    auth_type="Read Write"
else
    auth_type="Read"
fi

echo -e $auth_type

And when i execute it i got following output with errors.

./script.bash: line 5: SM_Read-only=Yes: command not found
./script.bash: line 6: SM_write-only=No: command not found
only
only
Read

Any one know correct way to declare the variable with "-" (dash)?

EDIT:

have getting response from c code and evaluate the variables for example

RESP=`getValue SM_ Read-only ,Write-only 2>${ERR_DEV}`
RC=$?
eval "$RESP"

from above scripts code my c binary getValue know that script want Read-only and Write-only and return value to script.So during eval $RESP in cause error and in my script i access variable by

echo -e  ${SM_Read-only}
echo -e  ${SM_Write-only}

which also cause error.

标签

评论

Rename the variable name as follows:

SM_Read_only="Yes"
SM_write_only="No"

Please, don't use - minus sign in variable names in bash, please refer to the answer, on how to set the proper variable name in bash.

However if you generate the code, based on others output, you can simply process their output with sed:

RESP=$(getValue SM_ Read-rule,Write-rule 2>${ERR_DEV}|sed "s/-/_/g")
RC=$?
eval "$RESP"

- is not allowed in shell variable names. Only letters, numbers, and underscore, and the first character must be a letter or underscore.

I think you cant have a dash in your variables names, only letters, digits and "_" Try:

SM_Read_only

Or

SM_ReadOnly

受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐
  • HOWTO:从shell脚本检测bash(HOWTO: Detect bash from shell script)
    问题 该方案是要求用户提供脚本文件的源: $ source envsetup.sh 该脚本文件可能仅使用bash功能,因此我们已检测到正在运行的shell是否为bash。 对于其他与bash共享通用语法的shell,例如sh,zsh,ksh,我要报告警告。 在Linux,Cygwin,OS X上检测当前shell的最可靠方法是什么? 我所知道的是$ BASH,但我想知道它可能失败的可能性。 回答1 您可以查看许多环境变量,但是其中许多变量将无法检测bash是否生成了其他shell。 考虑以下: bash$ echo "SHELL: $SHELL, shell: $shell, ARGV[0]: $0, PS1: $PS1, prompt: $prompt" SHELL: /bin/bash, shell: , ARGV[0]: -bash, PS1: bash$ , prompt: bash$ csh [lorien:~] daveshawley% echo "SHELL: $SHELL, shell: $shell, \$0: $0, PS1: $PS1, prompt: $prompt" SHELL: /bin/bash, shell: /bin/tcsh, ARGV[0]: csh, PS1: bash$ , prompt: [%m:%c3] %n%# [lorien:~]
  • Bash中有效标识符(例如函数,vars等)的规则是什么?(What are the rules for valid identifiers (e.g. functions, vars, etc) in Bash?)
    问题 Bash中标识符(特别是函数名和变量名)的语法规则是什么? 我编写了一个Bash脚本,并在Ubuntu,Debian,Red Hat 5和6甚至是旧的Solaris 8盒上的各种版本的Bash上进行了测试。 该脚本运行良好,因此已发布。 但是,当用户在SUSE计算机上尝试使用它时,它给出了“不是有效的标识符”错误。 幸运的是,我猜测函数名称中包含无效字符是正确的。 连字符把它弄乱了。 至少经过某种程度测试的脚本在另一个Bash或发行版上具有完全不同的行为,这一事实令人不安。 如何避免这种情况? 回答1 从手册中: Shell Function Definitions ... name () compound-command [redirection] function name [()] compound-command [redirection] name在其他地方定义: name A word consisting only of alphanumeric characters and under‐ scores, and beginning with an alphabetic character or an under‐ score. Also referred to as an identifier. 因此连字符无效。 但是,在我的系统上,它们确实可以工作... $
  • 《全面掌握Linux C语言嵌入式系统移植教程》学习笔记(Liunx速查简明)
    全面掌握Linux C语言嵌入式系统移植教程学习笔记(Liunx速查简明) 笔记前言:P3: shell命令简明P4: vi /vim编辑器入门P5:vi /vim编辑器扩展P8: gcc编译和调试初级P9: 数据类型1P10: 数据类型2P11,P12,P13:常量与变量P67:Linux 历史与发展P68,P69:deb软件包管理P70:Linux的shellP149:标准I/O上1(文件与流)P150:标准I/O上2(流的打开和关闭)P151:标准I/O上3(流的读写)P153:流的按对象读写P154:流的刷新,定位,是否出错和结束P155:流的格式化输出:P156,P157:Linux下的文件I/O:P73:shell命令P79:shell脚本编程P84:GDB调试P87:共用体与typedefP88,P89:内存管理P90,P91,P92:makefile(先学韦老师的)P158:文件属性,目录操作P159:库的基础知识和静态库的制作P160:共享库的制作P161:进程编程1P162:进程编程2P163,P164:进程编程3网络的封包与拆包网络基础知识网络编程的预备知识:socket,ip,端口和字节序 笔记前言: 很早的时候就听说过Linux 。我与Linux打招呼应该是高二的时候:买了个树莓派3B。 大一里做ROS机器人,搭web服务器;大二上搭编译服务器,缓存服务器
  • 是否可以编写一个在 bash/shell 和 PowerShell 中运行的脚本?(Is it possible to write one script that runs in bash/shell and PowerShell?)
    问题 我需要创建一个集成脚本来设置一些环境变量,使用 wget 下载一个文件并运行它。 挑战在于它需要是可以在 Windows PowerShell 和 bash / shell 上运行的相同脚本。 这是shell脚本: #!/bin/bash # download a script wget http://www.example.org/my.script -O my.script # set a couple of environment variables export script_source=http://www.example.org export some_value=floob # now execute the downloaded script bash ./my.script 这在 PowerShell 中是一样的: wget http://www.example.org/my.script -O my.script.ps1 $env:script_source="http://www.example.org" $env:some_value="floob" PowerShell -File ./my.script.ps1 所以我想知道这两个脚本是否可以合并并在任一平台上成功运行? 我一直试图找到一种方法将它们放在同一个脚本中,并让 bash 和
  • 如何确定我正在处理的当前 shell(How to determine the current shell I'm working on)
    问题 如何确定我正在处理的当前 shell? 仅ps命令的输出就足够了吗? 如何在不同风格的 Unix 中做到这一点? 回答1 有三种方法可以找到当前 shell 的可执行文件的名称: 请注意,如果 shell 的可执行文件是/bin/sh ,则所有三种方法都可能被愚弄,但它实际上是重命名的bash ,例如(经常发生)。 因此,你的第二个问题ps输出是否会做的回答是“不总是”。 echo $0 - 将打印程序名称...在外壳的情况下是实际的外壳。 ps -ef | grep $$ | grep -v grep ps -ef | grep $$ | grep -v grep - 这将在正在运行的进程列表中查找当前进程 ID。 由于当前进程是外壳程序,因此它将被包含在内。 这不是 100% 可靠的,因为您可能有其他进程的ps列表包含与 shell 的进程 ID 相同的数字,特别是如果该 ID 是一个小数字(例如,如果 shell 的 PID 为“5”,您可能会发现进程在同一个grep输出中称为“java5”或“perl5”!)。 这是“ps”方法的第二个问题,除了不能依赖外壳名称。 echo $SHELL - 当前 shell 的路径存储为任何 shell 的SHELL变量。 对此的警告是,如果您将 shell 作为子进程显式启动(例如,它不是您的登录 shell),您将获得登录
  • Shell常用命令
    SHELL 常见的Shell 查看shell 当前 Linux 系统可用的 Shell 都记录在/etc/shells文件中。/etc/shells是一个纯文本文件 $ cat /etc/shells /bin/sh /bin/bash /sbin/nologin /usr/bin/sh /usr/bin/bash /usr/sbin/nologin /bin/tcsh /bin/csh 在现代的 Linux 上,sh 已经被 bash 代替,/bin/sh往往是指向/bin/bash的符号链接 如果你希望查看当前 Linux 的默认 Shell,那么可以输出 SHELL 环境变量: $ echo $SHELL /bin/bash shell提示符 对于普通用户,Base shell 默认的提示符是美元符号$;对于超级用户(root 用户),Bash Shell 默认的提示符是井号#。该符号表示 Shell 等待输入命令 Shell 通过PS1和PS2两个环境变量来控制提示符格式: PS1 控制最外层命令行的提示符格式。PS2 控制第二层命令行的提示符格式。 要显示提示符的当前格式,可以使用 echo 输出 PS1 和 PS2: [mozhiyan@localhost ~]$ echo $PS1 [\u@\h \W]\$ [mozhiyan@localhost ~]$ echo
  • "bad variable name" using "read var"
    I am getting confused about Linux shells. It may be that I oversee something obvious as a Linux noob. All I want is the following script to run: #!/bin/bash echo "Type some Text:" read var echo "You entered: "$var Here is the situation: Installed Ubuntu Server 14.04 in a VirtualBox on windows Installed it with this packages A SAMBA mounted on /media/buff The script is on /media/buff/ShellScript/test.sh made executable by "sudo chmod a+x /media/buff/ShellScript/test.sh" The rest is default I am using PSPad on windows to edit the script file I read about the dash but I'm not getting it. Here are
  • 编写一个基本的 Shell(Writing a Basic Shell)
    问题 对于我的课程,我必须创建一个类似于 bash 的基本 shell,它允许用户调用 ls、sleep 等命令。我正在寻找有关如何执行此操作的资源:教程、帮助文本、示例代码,甚至只是一些关于如何开始的一般信息。 有没有人有链接或信息来帮助我? 回答1 这实际上取决于您的外壳必须有多简单。 如果您不需要作业控制(即后台)或管道,那么它非常简单。 下面是一个例子: #include <stdio.h> #include <stdlib.h> #define MAX_LENGTH 1024 int main(int argc, char *argv[]) { char line[MAX_LENGTH]; while (1) { printf("$ "); if (!fgets(line, MAX_LENGTH, stdin)) break; system(line); } return 0; } 您可以使用 CTRL-D 退出上述示例。 要添加诸如exit或cd 之类的内置命令,您必须使用strtok()对该行进行标记并查看第一个标记。 这是一个更复杂的示例,添加了这些命令: #include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> #ifdef _WIN32 #include
  • 为什么在Shell脚本中未扩展路径中的代字号?(Why is a tilde in a path not expanded in a shell script?)
    问题 我试图让Android Studio启动器(studio.sh)使用手动安装的Java(而不是系统范围的默认Java)。 因为我已经在.bashrc文件中声明了PATH和JAVA_HOME,所以我只是在shell脚本中获取了该文件: 。 /home/foobar/.bashrc 但是由于某种原因,该脚本仍无法将$ JAVA_HOME / bin / java识别为可执行文件。 我添加了一些日志记录,发现JAVA_HOME已扩展为〜/ install / java ...,即,代字号运算符未扩展到主目录中。 我进行了一些搜索,但是找不到任何未扩展的原因。 tilde是Bash特有的功能吗(脚本使用#!/ bin / sh,Linux Mint使用破折号而不是bash)? 波浪号在某些情况下不起作用吗? 我在.bashrc声明中用$ HOME替换〜,然后它起作用了,因此在运行时就知道HOME了。 回答1 在bash手册中,请注意在参数替换过程中括号的扩展,但不是递归的: 扩展的顺序是:大括号扩展; 波浪线扩展,参数和变量扩展,算术扩展和命令替换(以从左到右的方式完成); 分词和文件名扩展。 这意味着未扩展存储在bash变量中的任何代字号(或参数引用或命令替换)都不会自动解析。 您的JAVA_HOME变量包含文字波浪号,因此bash不会自动对其进行扩展。 您的修复很可能有效
  • 我在什么壳里?(What shell am I in?)
    问题 是否有命令标识当前外壳程序的名称/类型,外壳程序二进制文件的路径以及外壳程序的版本? 我不需要所有这些,但是我能得到的越多越好。 我想要一种具有一样的uname , pwd和whoami感觉的东西。 只是一个简单的实用程序,带有简单的输出。 (到目前为止尚未出现:/) 再ps $ ps -o comm $$ COMM -bash 为什么使用-bash而不是使用其他所有路径的完整路径? 那里的破折号怎么处理? 回答1 当前运行的shell的命令或路径存储在环境变量$0 。 要查看其价值,请使用: echo $0 这将输出当前正在运行的shell或当前正在运行的shell的路径,具体取决于调用它的方式。 可能需要一些处理: prompt:~$ echo $0 /bin/bash prompt:~$ sh sh-4.0$ echo $0 sh sh-4.0$ exit exit prompt:~$ /bin/sh sh-4.0$ echo $0 /bin/sh sh-4.0$ $SHELL环境变量包含用户的首选shell,不一定包含当前正在运行的shell。 回答2 如果您没有在shebang行中指定程序,我相信将使用/ bin / sh。 不幸的是,我不认为有什么好的便携式方法可以确定该外壳是什么。 如果您使用的是Linux,则可以通过/proc查找可执行文件路径: $
  • Bash:语法错误:重定向意外(Bash: Syntax error: redirection unexpected)
    问题 我在脚本中执行此操作: read direc <<< $(basename `pwd`) 我得到: Syntax error: redirection unexpected 在Ubuntu机器上 /bin/bash --version GNU bash, version 4.0.33(1)-release (x86_64-pc-linux-gnu) 虽然我在另一台suse机器上没有收到此错误: /bin/bash --version GNU bash, version 3.2.39(1)-release (x86_64-suse-linux-gnu) Copyright (C) 2007 Free Software Foundation, Inc. 为什么会出错? 回答1 您的脚本在其哈希爆炸行中引用了/bin/bash或/bin/sh吗? Ubuntu中的默认系统外壳是破折号,而不是bash,因此,如果您使用#!/bin/sh则脚本将使用与您期望的外壳不同的外壳。 Dash没有<<<重定向运算符。 回答2 如果您使用以下命令来运行脚本: sudo sh ./script.sh 然后,您将要使用以下内容: sudo bash ./script.sh 原因是Bash不是Ubuntu的默认外壳。 因此,如果您使用“ sh”,它将仅使用默认外壳程序;否则,将使用默认外壳程序。
  • 我应该使用什么Linux shell? [关闭](What Linux shell should I use? [closed])
    问题 关门了。 这个问题是基于意见的。 它当前不接受答案。 想要改善这个问题吗? 更新问题,以便可以通过编辑此帖子以事实和引用的形式回答。 5年前关闭。 改善这个问题 我用过bash,csh和tcsh。 但是我问了这个问题,乔纳森告诉我,不要信任csh。 因此,什么Linux shell有利于开发。 为什么呢? 回答1 到目前为止,在Linux上最常见的外壳是bash。 除非您有充分的理由使用替代方法,否则我建议坚持使用bash或项目团队最常用的shell(或必须使用的大量shell脚本)。 另一个非常常见的竞争者是破折号,它已在Ubuntu项目中得到越来越广泛的使用。 好吧,这确实是个人喜好,但csh除外。 csh的维基百科链接 回答2 我更喜欢zsh。 仅制表符补全是值得的: 如果需要的话,它会扩展通配符(要删除目录中除一个文件外的所有文件,非常方便) 指定程序后将为您提供开关列表在您正在处理的行下方提供制表符完成选项,这非常方便。 http://zsh.sourceforge.net/ 回答3 为了实现交互性,请使用Zsh。 一段时间以来,我一直是Bash制表符完成脚本的FreeBSD端口的维护者,但是当我第一次尝试Zsh时就放弃了它。 它可以执行Bash可以执行的所有操作,但是更轻松,更优雅。 它还具有非常类似于Bash的击键的好属性,因此,如果您使用的系统没有Zsh
  • Linux Shell脚本调试的四种办法
    Linux脚本调试 前言bash自身特性-v-n-x-x的增强$LINENO$FUNCNAME$[PS4](https://blog.51cto.com/kusorz/1968827) trap调试钩子bashdb 前言 Linux的shell脚本上手简单但是调试起来就颇为麻烦,二者间的抉择就像编辑器上轻量级与功能丰富的不可兼得一般。在这里提出一些Linux上脚本调试的小技巧,希望有所帮助。 bash自身特性 众所周知,bash相对于dash而言是更重量级的存在,其中一部分便是这种调试辅助信息。以下的特性都是在bash上验证的,dash下无说明便是没有测试过。 了解一个命令的最好办法自然是man手册: 手册本身命令很多,这次只介绍几个我常用的参数: -v 一边执行脚本,一边将执行过的脚本命令打印。 注意: 脚本命令本身是被定义到标准错误输出打印,而真实结果是在标准输出打印。 -n 读一遍脚本中的命令但不执行,用于检查脚本中的语法错误。 注意:这里的检查主要是针对语法格式缺少(例如,if语句少了then),但是还有很多是没有检查的(比如,if语句没加空格、函数未定义)。 -x 提供跟踪执行信息,将执行的每一条命令和结果依次打印出来。这个的功能超级强大,将会重点介绍。 如果有多个脚本嵌套关系,可以进入次级脚本检查(比如a.sh调用b.sh,b.sh调用c.sh,只会显示a.sh和b
  • 在printf中填充字符(Padding characters in printf)
    问题 我正在编写一个bash shell脚本,以显示某个进程是否正在运行。 到目前为止,我得到了: printf "%-50s %s\n" $PROC_NAME [UP] 该代码给了我这个输出: JBoss [DOWN] GlassFish [UP] verylongprocessname [UP] 我想用'-'或'*'填充两个字段之间的间隙,以使其更具可读性。 在不干扰字段对齐的情况下该如何做? 我想要的输出是: JBoss ------------------------------------------- [DOWN] GlassFish --------------------------------------- [UP] verylongprocessname ----------------------------- [UP] 回答1 纯Bash,无需外部实用程序 该演示进行了充分的论证,但是如果您想要的是参差不齐的右行,则可以省略第二个字符串的长度。 pad=$(printf '%0.1s' "-"{1..60}) padlength=40 string2='bbbbbbb' for string1 in a aa aaaa aaaaaaaa do printf '%s' "$string1" printf '%*.*s' 0 $((padlength - ${
  • 关联数组:错误“声明:-A:无效选项”(Associative arrays: error “declare: -A: invalid option”)
    问题 我编写了一个在bash(v 4)中使用关联数组的脚本。 在使用4.1.5(1)-release本地计算机上,它可以正常工作。 在生产计算机上,使用4.1.0(1)-release ,以下行声明assoc数组失败: declare -A uniqjars 消息: /script.sh: line 11: declare: -A: invalid option declare: usage: declare [-afFirtx] [-p] [name[=value] ...] 我的印象是这是bash 4的一项常规功能? 在生产机器上使用bash的人中,它讨论了使用-A因此我认为它应该可以工作。 关联数组是使用declare -A name创建的。 我可以确认脚本打印出的值,使用bash的正确版本echo 'bash -version 。 我可能做错了什么? 回答1 确保在shell脚本顶部以解释器形式调用的bash版本( #!/bin/bash或其他版本)也为版本4。 bash --version 然后给您v4,执行一次which bash检查其位置。 回答2 如果您想在bash v3中将chars用作数组索引,则可以采用以下解决方法: array=( 'hello::world.' 'nice::to meet you' ) for index in "${array[@]}"
  • Bash script execution with and without shebang in Linux and BSD
    How and who determines what executes when a Bash-like script is executed as a binary without a shebang? I guess that running a normal script with shebang is handled with binfmt_script Linux module, which checks a shebang, parses command line and runs designated script interpreter. But what happens when someone runs a script without a shebang? I've tested the direct execv approach and found out that there's no kernel magic in there - i.e. a file like that: $ cat target-script echo Hello echo "bash: $BASH_VERSION" echo "zsh: $ZSH_VERSION" Running compiled C program that does just an execv call
  • 如何检测脚本是否源(How to detect if a script is being sourced)
    问题 我有一个脚本,如果它是源代码,我不希望它调用exit 。 我考虑过检查$0 == bash但是如果脚本是从另一个脚本中获取的,或者用户是从另一个类似ksh外壳中获取的,这就会出现问题。 有没有可靠的方法来检测脚本是否源? 回答1 这似乎可以在Bash和Korn之间移植: [[ $_ != $0 ]] && echo "Script is being sourced" || echo "Script is a subshell" 与此类似的行或类似pathname="$_"的赋值(带有稍后的测试和操作)必须位于脚本的第一行或shebang之后的行中(如果使用的话,应用于ksh in)以便在大多数情况下都可以正常工作)。 回答2 如果您的Bash版本知道BASH_SOURCE数组变量,请尝试以下操作: # man bash | less -p BASH_SOURCE #[[ ${BASH_VERSINFO[0]} -le 2 ]] && echo 'No BASH_SOURCE array variable' && exit 1 [[ "${BASH_SOURCE[0]}" != "${0}" ]] && echo "script ${BASH_SOURCE[0]} is being sourced ..." 回答3 针对bash , ksh , zsh可靠解决方案
  • 如何在 shell 脚本中通过 SSH 运行函数和本地资源(How to run functions and local resources over SSH in a shell script)
    问题 我有一个像这样的shell脚本文件: #!/bin/bash CONF_FILE="/tmp/settings.conf" #settings.conf contains OS_NAME="Caine Linux" source $CONF_FILE display_os_name() { echo "My OS is:" $OS_NAME } #using the function locally works fine display_os_name #displays: My OS is: Caine Linux #using the function on the remote host doesn't work ssh user@host "$(declare -f); display_os_name" #displays: My OS is: 如果我删除-f并且我只使用ssh user@host "$(declare); display_os_name"它可以工作但会显示这些错误和警告: bash: line 10: BASHOPTS: readonly variable bash: line 18: BASH_VERSINFO: readonly variable bash: line 26: EUID: readonly variable bash: line
  • bash : 错误的替换(bash : Bad Substitution)
    问题 #!/bin/bash jobname="job_201312161447_0003" jobname_pre=${jobname:0:16} jobname_post=${jobname:17} 这个 bash 脚本在 ubuntu 上给了我错误的替换错误。 任何帮助将不胜感激。 回答1 Ubuntu 下的默认 shell ( /bin/sh ) 指向dash ,而不是bash 。 me@pc:~$ readlink -f $(which sh) /bin/dash 因此,如果您chmod +x your_script_file.sh然后使用./your_script_file.sh运行它,或者如果您使用bash your_script_file.sh运行它,它应该可以正常工作。 使用sh your_script_file.sh运行它将不起作用,因为 hashbang 行将被忽略并且脚本将由dash解释,它不支持该字符串替换语法。 回答2 我有同样的问题。 确保你的脚本没有 #!/bin/sh 在脚本的顶部。 相反,您应该添加 #!/bin/bash 回答3 对于到达这里的其他人,使用 env 变量语法进行命令时也会出现此确切消息,例如${which sh}而不是正确的$(which sh) 回答4 您的脚本语法是有效的 bash 并且很好。 失败的可能原因:
  • 如何将当前工作目录设置为Bash中脚本的目录?(How can I set the current working directory to the directory of the script in Bash?)
    问题 我正在写一个Bash脚本。 我需要当前的工作目录始终是脚本所在的目录。 默认行为是脚本中的当前工作目录是运行它的外壳程序的目录,但是我不希望出现这种情况。 回答1 #!/bin/bash cd "$(dirname "$0")" 回答2 以下内容也适用: cd "${0%/*}" 该StackOverflow答案中对语法进行了详细说明。 回答3 尝试以下简单的一线: 对于所有UNIX / OSX / Linux dir=$(cd -P -- "$(dirname -- "$0")" && pwd -P) 重击 dir=$(cd -P -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P) 注意:命令中使用双破折号(-)表示命令选项的结尾,因此包含破折号或其他特殊字符的文件不会破坏命令。 注意:在bash,使用${BASH_SOURCE[0]}赞成$0 ,否则路径可以采购它时破裂( source / . )。 对于Linux,Mac和其他* BSD: cd "$(dirname "$(realpath "$0")")"; 注意:默认情况下, realpath应该安装在最受欢迎的Linux发行版中(例如Ubuntu),但是在某些情况下可能会丢失,因此必须安装它。 注意:如果你正在使用bash,使用${BASH_SOURCE[0]}赞成