4

我希望我的 bash 脚本检查运行它的目录的名称。就像是:

#!/bin/bash

path=eval 'pwd'

dirname=eval 'basename $path'

但它不起作用:我明白了

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

我该如何解决?此外,一旦我让 dirname 包含正确的 dirname,我想将其转换为小写,以进行测试。我可以使用 awk 在命令行上执行此操作:

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

但是如何将返回值捕获到变量中?

4

7 回答 7

3

为什么不使用:

#!/bin/bash

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

或者,如果您想将其作为一个班轮:

dirname=`pwd | xargs basename | awk '{print tolower($0)}'`
于 2012-10-02T12:21:18.317 回答
2

表格

x=y cmd

意味着临时将环境变量设置x为 valuey然后 run cmd,这就是这些行的解释方式:

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

也就是说,它们根本没有按照您的预期做,而是将环境变量设置为文字值eval,然后运行(或找不到)命令。正如其他人所说,将命令结果插入字符串的方法是将其放入$(...)(首选)或`...`(旧版)中。而且,作为一般规则,将它们包含在双引号中更安全(因为将任何插值引用包含在引号中更安全)。

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

(从技术上讲,在这种情况下,外部引号并不是绝对必要的。但是,我想说这仍然是一个好习惯。)

于 2012-10-02T13:15:34.850 回答
2

您可以将其重写为

dirname=eval "basename $path"

使用单引号,您不会获得 shell 扩展,但您希望$path得到扩展。

顺便说一句:我建议使用

path=$(basename $path)

如果你做类似的事情,它会更通用,可读性更好

path=$(basename $(pwd))

或得到小写结果

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

或者

path=$(basename $(pwd) | tr 'A-Z' 'a-z' )
于 2012-10-02T12:22:55.960 回答
0
B=$(echo "Some text that has CAPITAL letters " | awk '{print tolower($0)}')
于 2012-10-02T12:22:43.550 回答
0
于 2013-11-26T20:27:02.593 回答
0

eval 执行传递给它的命令,但它只返回命令退出状态码,所以你不能真正在 set 运算符中使用它。将命令嵌入到集合运算符中的方法是使用右单引号或$()

所以脚本将如下所示:

#!/bin/bash

curr_path=$(pwd)
echo $curr_path
curr_dir=$(basename $curr_path)
echo $curr_dir
echo $curr_dir | awk '{print tolower($0)}'
于 2012-10-02T12:28:20.233 回答
0

您的代码不起作用,因为您使用单引号而不是双引号。单引号可防止变量扩展,因此$path不会扩展为您要使用的路径,而是按原样使用,就好像它是一个字符串一样。

由于同样的原因,您的 awk 调用也不起作用。

尽管您可以解决用双引号替换单引号的问题,如下所示:

#!/bin/bash

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

我建议改用重音(). There's no reason to use在这种情况下为 eval`。另外,您还可以使用它来收集您感兴趣的返回值:

#!/bin/bash

path=`pwd`
dirname=`basename $path`
variable=`echo $dirname | awk "{print tolower($0)}"`
于 2012-10-02T13:22:10.903 回答