shell脚本:检查目录名和转换为小写(shell script: check directory

2019-09-23 08:23发布

我想我的bash脚本来检查其运行所在的目录名。 就像是:

#!/bin/bash

path=eval 'pwd'

dirname=eval 'basename $path'

但它不工作:我得到

./foo.sh: line 5: basename $path: command not found

我怎样才能解决这个问题? 此外,一旦我得到目录名称包含正确的目录名称,我想将其转换为小写,以测试它。 我能够做到这一点使用awk在命令行:

echo $dirname | awk '{print tolower($0)}'

但我如何获取返回值到一个变量? 先感谢您,

最好的祝福

塞尔吉奥

Answer 1:

为什么不使用:

#!/bin/bash

path=`pwd`
dirname=`basename $path | awk '{print tolower($0)}'`

或者,如果你想要做它作为一个班轮:

dirname=`pwd | xargs basename | awk '{print tolower($0)}'`


Answer 2:

你可以把它重写

dirname=eval "basename $path"

使用单引号,你没有得到shell扩展,但你要$path得到扩大。

BTW:我suggesst使用

path=$(basename $path)

它的方式更通用的和更好的可读性,如果你这样做

path=$(basename $(pwd))

或获得小写结果

path=$(basename $(pwd) | awk '{print tolower($0)}')

要么

path=$(basename $(pwd) | tr 'A-Z' 'a-z' )


Answer 3:

表格

x=y cmd

指暂时设置的环境变量x对值y然后运行cmd ,这是怎么这些行解释:

path=eval 'pwd'
dirname=eval 'basename $path'

也就是说,他们不这样做,你似乎期望所有的东西,而不是设置环境变量的文字值eval ,然后运行(或者没有找到)的命令。 正如其他人所说,将一个命令的结果插值到一个字符串的方法是把它里面$(...)首选)或`...`传统)。 而且,作为一般规则,它的安全包裹那些在双引号(因为它是安全的用引号括任何插参考)。

path="$(pwd)"
dirname="$(basename "$path")"

(从技术上说,在这种情况下,外引号不是必须的。但是,我会说这仍然是一个好习惯。)



Answer 4:

B=$(echo "Some text that has CAPITAL letters " | awk '{print tolower($0)}')


Answer 5:

EVAL执行传递给它的命令,但它只返回命令的退出状态代码,所以你不能真正在集合运算符使用。 要走的路嵌入到命令集合运算符要么使用权单引号或$()

因此,该脚本将是这样的:

#!/bin/bash

curr_path=$(pwd)
echo $curr_path
curr_dir=$(basename $curr_path)
echo $curr_dir
echo $curr_dir | awk '{print tolower($0)}'


Answer 6:

您的代码不工作,因为你用单引号,而不是双引号。 单引号阻止变量扩展,从而$path没有扩展到要使用,并采取的路径,因为它是,因为它是如果一个字符串。

你AWK调用不会出于同样的原因以及工作。

虽然可以解决替换单引号与双引号,像这样的问题:

#!/bin/bash

path=eval "pwd"
dirname=eval "basename $path"

我会建议使用重音符,而不是( ). There's no reason to use ). There's no reason to use在这种情况下eval`。 另外,你也可以用它来收集返回值,你感兴趣的是:

#!/bin/bash

path=`pwd`
dirname=`basename $path`
variable=`echo $dirname | awk "{print tolower($0)}"`


Answer 7:

下面是我的回答摘录找到外壳可执行文件的目录中的shell脚本什么平台独立的方式? 其中,在本身,完全应答来自小写的一部分,这在我看来,已经正式在其他的答案解决了许多次在这里你的问题放在一边。

什么是我的唯一答案是,当我试图把它写我遇到你确切的问题其他问题- 如何将功能的结果存储在一个变量? 好了,你可以看到,有一些帮助,我想出了一个非常简单,非常强大的解决方案:

我可以通过功能的排序信使变量和反引用任何明确的使用所产生的函数的参数的的$1名与eval是必要的,而且,功能程序的完成时,我使用eval和一个反斜杠引述招分配我的使者变量的值我渴望而不必知道它的名字。

在充分披露,尽管这是解决我的问题,这是以任何方式我的解决方案。 我已经数次前游,但他的一些描述,虽然可能辉煌,有一点我配不上,所以我想,如果包括我自己是如何工作的前一段的版本等可能受益。 当然尽管这是非常简单的了解,一旦我做到了,这一个特别,我不得不想到漫长而艰难弄清楚它如何工作。 无论如何,你可以发现,多在丰富的SH技巧 ,我也摘录他的网页的相关部分低于我自己的答案的摘录。

... 摘录:...

虽然没有严格的POSIX的是, 真实路径是自2012年GNU核心应用。 全面披露:从来没有听说过它之前,我在发现它info coreutils TOC,马上想到的[链接]问题,但使用这表现应该可靠,(?很快POSIXLY),并且,我希望,有效地提供以下功能的来电者有绝对货源$0

% _abs_0() { 
> o1="${1%%/*}"; ${o1:="${1}"}; ${o1:=`realpath "${1}"`}; eval "$1=\${o1}"; 
> }  
% _abs_0 ${abs0:="${0}"} ; printf %s\\n "${abs0}"
/no/more/dots/in/your/path2.sh

编辑:这可能是值得强调的是这个解决方案使用POSIX参数扩展首先检查路径实际需要扩大,并试图这样做之前解决的。 这应返回的绝对来源$0通过信使变量 (与显着的例外,它会保留symlinks尽可能有效地我能想象这是可以做到的路线是否已经是绝对的。 ...

次要编辑 :找到之前realpath的文档,我已经至少缩减了我的版本的[版本下方]不依赖于时间领域,因为它在第一次做ps命令],但是,公平的警告,经过测试一些我不太相信ps是在其命令路径的扩展能力完全可靠)

在另一方面,你可以这样做:

ps ww -fp $$ | grep -Eo '/[^:]*'"${0#*/}"

eval "abs0=${`ps ww -fp $$ | grep -Eo ' /'`#?}"

...... 而从丰富的SH招数 :...

从shell函数返回一个字符串

如可以从命令替换的上述缺陷可以看出,由于输出是不是一个好途径壳功能的字符串返回到其调用者,除非输出处于格式,其中拖尾换行符是微不足道的。 当然,这样的做法是不是意味着处理任意字符串的函数可以接受的。 那么,什么可以做什么?

尝试这个:

func () {
body here
eval "$1=\${foo}"
}

当然, ${foo}可以通过任何一种替代的替代。 这里的关键诀窍就是eval线和使用逃逸。 在“$1”时的参数EVAL由主命令解析器构造已展开。 但“${foo}”是不是在这个阶段扩大,因为“$”被引用。 相反,当EVAL评估其论点它的扩展。 如果还不清楚为什么这很重要,请考虑以下怎么会不好:

foo='hello ; rm -rf /'
dest=bar
eval "$dest=$foo"

但当然,下面的版本是完全安全的:

foo='hello ; rm -rf /'
dest=bar
eval "$dest=\$foo"

需要注意的是在原来的例子, “$1”来允许呼叫者通过目标变量名作为参数的函数。 如果你的函数需要使用shift命令,例如处理其余的参数为“$@” ,那么它可能是用来保存的价值“$1”在一个临时变量的函数的开始。



文章来源: shell script: check directory name and convert to lowercase
标签: bash shell awk