[[$ {1:0:1}“ ='-']的含义


18

我有以下脚本来启动MySQL进程:

if [ "${1:0:1}" = '-' ]; then
    set -- mysqld_safe "$@"
fi

if [ "$1" = 'mysqld_safe' ]; then
    DATADIR="/var/lib/mysql"
...

1:0:1在这种情况下是什么意思?


1
我真的很想知道答案,但是我觉得对于SF来说,这是一个太狭窄的问题。我投票将其迁移到Unix站点。
Massimo 2015年

Answers:


19

-显然,这是对虚线参数选项的测试。确实有点奇怪。它使用非标准bash扩展来尝试从中提取第一个和唯一的第一个字符$1。的0是头部字符索引和1是字符串长度。在[ test这样说,这也可能是:

[ " -${1#?}" = " $1" ]

test但是,这两种比较都不特别适合,因为它也可以解释-虚线参数-这就是为什么我在此处使用前导空格。

做这种事情的最佳方法(通常是通常的方法)是:

case $1 in -*) mysqld_safe "$@"; esac

1
关; 第二个冒号后面的数字${1:0:1}是长度,而不是索引。
chepner

以暴力的方式与[[[[ $1 == -* ]]
Arthur2e5

2
我个人不认为这些-将是一个问题test在这里.. POSIX给出了参数计数的含义定义。由于没有这样的选项带有两个参数,因此以原始方式编写它应该是安全的。
Arthur2e5

@ Arthur2e5-你是对的-他们不应该是一个问题-很可能根本没有问题。这仍然是一个奇怪的方法-不合适。怎么[[ : [[办?
mikeserv

1
@mikeserv好吧,您应该看一下该网页(如果您从其他地方阅读)。第一个[[只是语法名称,而冒号只是一个标点符号。
Arthur2e5

11

这将采用$1从第0个字符到第一个字符的子字符串。因此,您将获得字符串的第一个字符,只有第一个字符。

bash3.2手册页:

  ${parameter:offset}
  ${parameter:offset:length}
          Substring  Expansion.   Expands  to  up to length characters of
          parameter starting at the character specified  by  offset.   If
          length is omitted, expands to the substring of parameter start-
          ing at the character specified by offset.   length  and  offset
          are  arithmetic  expressions (see ARITHMETIC EVALUATION below).
          length must evaluate to a number greater than or equal to zero.
          If  offset  evaluates  to a number less than zero, the value is
          used as an offset from the end of the value of  parameter.   If
          parameter  is  @,  the  result  is length positional parameters
          beginning at offset.  If parameter is an array name indexed  by
          @ or *, the result is the length members of the array beginning
          with ${parameter[offset]}.  A negative offset is taken relative
          to  one  greater than the maximum index of the specified array.
          Note that a negative offset must be separated from the colon by
          at  least  one space to avoid being confused with the :- expan-
          sion.  Substring indexing is zero-based unless  the  positional
          parameters are used, in which case the indexing starts at 1.

6

正在测试第一个参数的第一个字符$1是破折号-

1:0:1是参数扩展的值:${parameter:offset:length}

这意味着:

  • 名称:名为的参数1,即:$1
  • 开始:从第一个字符开始0(从0 开始编号)。
  • 长度:1个字符。

简而言之:第一个位置参数的第一个字符$1
该参数扩展在ksh,bash,zsh(至少)中可用。


如果要更改测试行:

[ "${1:0:1}" = "-" ]

重击选项

其他更安全的bash解决方案可能是:

[[ $1 =~ ^- ]]
[[ $1 == -* ]]

更安全,因为这没有引号问题(在内部不执行拆分[[

POSIXly选项。

对于能力较弱的较旧的外壳,可以更改为:

[ "$(echo $1 | cut -c 1)" = "-" ]
[ "${1%%"${1#?}"}"        = "-" ]
case $1 in  -*) set -- mysqld_safe "$@";; esac

只有case命令更能抵抗错误的引用。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.