Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash使用子shell和子字符串进行错误替换_Bash_String_Substitution_Subshell - Fatal编程技术网

Bash使用子shell和子字符串进行错误替换

Bash使用子shell和子字符串进行错误替换,bash,string,substitution,subshell,Bash,String,Substitution,Subshell,一个人为的例子。。。给定 FOO="/foo/bar/baz" 这是有效的(在bash中) 这并不重要 BAZ=${$(basename $FOO):0:1} # result is bad substitution 我的问题是,哪条规则导致[子shell替换]的计算不正确?如果有正确的方法,在一跳中做这件事的正确方法是什么?修改过的参数替换形式,如${parameter#word}只能修改一个参数,不能修改任意单词 在这种情况下,您可以通过管道将basename的输出传输到dd命令,如 B

一个人为的例子。。。给定

FOO="/foo/bar/baz"
这是有效的(在bash中)

这并不重要

BAZ=${$(basename $FOO):0:1} # result is bad substitution

我的问题是,哪条规则导致[子shell替换]的计算不正确?如果有正确的方法,在一跳中做这件事的正确方法是什么?

修改过的参数替换形式,如
${parameter#word}
只能修改一个参数,不能修改任意单词

在这种情况下,您可以通过管道将
basename
的输出传输到dd命令,如

BAR=$(basename -- "$FOO" | dd bs=1 count=1 2>/dev/null)
(如果您想要更高的计数,请增加
count
而不是
bs
,否则您得到的字节可能比请求的字节少。)


在一般情况下,没有办法在一次赋值中执行类似操作。

它失败,因为
${BAR:0:1}
是一个变量展开。Bash希望在
${
之后看到一个变量名,而不是一个值


我不知道如何在一个表达式中实现它。

首先,请注意,当您这样说时:

BAR=$(basename $FOO) # result is BAR="baz"
BAZ=${BAR:0:1}       # result is BAZ="b"
BAZ
的构造中的第一位是
BAR
,而不是您想要获取的第一个字符的值。因此,即使bash允许变量名包含任意字符,第二个表达式中的结果也不是您想要的

但是,关于阻止这种情况发生的规则,请允许我引用bash手册页中的内容:

DEFINITIONS
       The following definitions are used throughout the rest  of  this  docu‐
       ment.
       blank  A space or tab.
       word   A  sequence  of  characters  considered  as a single unit by the
              shell.  Also known as a token.
       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.
再过一会儿:

PARAMETERS
       A parameter is an entity that stores values.  It can be a name, a  num‐
       ber, or one of the special characters listed below under Special Param‐
       eters.  A variable is a parameter denoted by a name.  A variable has  a
       value  and  zero or more attributes.  Attributes are assigned using the
       declare builtin command (see declare below in SHELL BUILTIN COMMANDS).
稍后,当它定义您要询问的语法时:

   ${parameter:offset:length}
          Substring Expansion.  Expands to  up  to  length  characters  of
          parameter  starting  at  the  character specified by offset.
因此,手册页中阐明的规则规定,
${foo:x:y}
构造必须有一个参数作为第一部分,并且参数只能是名称、数字或少数特殊参数字符中的一个。
$(basename$foo)
不是参数允许的可能性之一


至于在一个赋值中执行此操作的方法,请使用管道到其他响应中提到的其他命令。

${string:0:1},string必须是变量名

例如:

FOO=“/FOO/bar/baz”

baz=“foo”

BAZ=
eval echo'${'$(basename$FOO)“':0:1}'

echo$BAZ


结果是“f”

正如其他人所说,${}的第一个参数需要是一个变量名。但是您可以使用另一个子shell来近似您要做的事情

而不是:

BAZ=${$(basename $FOO):0:1} # result is bad substitution
使用:


针对您的人为示例的人为解决方案:

BAZ=$(expr $(basename $FOO) : '\(.\)')

BAZ=$(_TMP=$(basename $FOO); echo ${_TMP:0:1}) # this works
BAZ=$(expr $(basename $FOO) : '\(.\)')
$ FOO=/abc/def/ghi/jkl
$ BAZ=$(expr $(basename $FOO) : '\(.\)')
$ echo $BAZ
j