bash 从函数返回值的脚本

bash scripting on returning values from functions

我有一个 bash 方法,看起来像这样

function getServiceId() {
    serviceId=$(docker -H  ps -qf label=com.docker.swarm.service.name=)
    =serviceId
    return 0
}

我这样执行这个函数

getServiceId $node1 $service1 retVal

错误来自第 =serviceId 行。 它试图在 bash 上执行 serviceId 的值,认为它是一个 bash 命令。我的目标是 return 变量 serviceId 中的值。 我该怎么做?

只需捕获 getServiceId 函数的 STDOUT。

function getServiceId() {
    docker -H "" ps -qf "label=com.docker.swarm.service.name="
}

serviceId="$(getServiceId "arg1" "arg2")"
echo "Service ID is $serviceId"

您不会 return 来自 shell 中函数的值;您写入标准输出,或设置全局变量。 (没有人说过 shell 促进了良好的软件工程实践。)

getServiceId () {
    docker -H "" ps -qf label=com.docker.swarm.service.name=""
}

serviceID=$(getServiceID)

getServiceID () {
    serviceID=$(docker -H "" ps -qf label=com.docker.swarm.service.name="")
}

试试这个:

function getServiceId() {
    local serviceId
    read serviceId  < <(
        docker -H  ps -qf label=com.docker.swarm.service.name=
    )
    printf -v  "%s" "$serviceId"
}

getServiceId $node1 $service1 retVal

这适用于 这个 特定情况。但我喜欢使用 read 为很多东西设置变量,例如:

{ read foo ; read device total use free prct mpoint } < <(df -k /)
echo $use

# Work on DB
while IFS=$'\t' read id name label ;do
    [ "$id" ] && (( id > 100 )) && {
         # Doing something for entries with id > 100 ...
    }
done < <(
    sqlclient "SELECT id,name,label FROM ..."
)

但要注意:默认情况下 read 会将 解释 反斜杠 \escape char(擦除换行符, 例如)。见 help read:

read: read [-ers] [-a array] [-d delim] [-i text] [-n nchars] [-N nchars] [-p prompt] [-t timeout] [-u fd] [name ...]
   Read a line from the standard input and split it into fields.

   Reads a single line from the standard input, or from file descriptor FD
   if the -u option is supplied.  The line is split into fields as with word
   splitting, and the first word is assigned to the first NAME, the second
   word to the second NAME, and so on, with any leftover words assigned to
   the last NAME.  Only the characters found in $IFS are recognized as word
   delimiters.

   If no NAMEs are supplied, the line read is stored in the REPLY variable.

   Options:
     -a array assign the words read to sequential indices of the array
          variable ARRAY, starting at zero
     -d delim continue until the first character of DELIM is read, rather
          than newline
     -e       use Readline to obtain the line in an interactive shell
     -i text  Use TEXT as the initial text for Readline
     -n nchars    return after reading NCHARS characters rather than waiting
          for a newline, but honor a delimiter if fewer than NCHARS
          characters are read before the delimiter
     -N nchars    return only after reading exactly NCHARS characters, unless
          EOF is encountered or read times out, ignoring any delimiter
     -p prompt    output the string PROMPT without a trailing newline before
          attempting to read
     -r       do not allow backslashes to escape any characters
     -s       do not echo input coming from a terminal
     -t timeout   time out and return failure if a complete line of input is
          not read within TIMEOUT seconds.  The value of the TMOUT
          variable is the default timeout.  TIMEOUT may be a
          fractional number.  If TIMEOUT is 0, read returns immediately,
          without trying to read any data, returning success only if
          input is available on the specified file descriptor.  The
          exit status is greater than 128 if the timeout is exceeded
     -u fd        read from file descriptor FD instead of the standard input

   Exit Status:
   The return code is zero, unless end-of-file is encountered, read times out
   (in which case it's greater than 128), a variable assignment error occurs,
   or an invalid file descriptor is supplied as the argument to -u.