当我在bash脚本中的另一个函数中调用函数时,为什么没有获得值

时间:2019-05-23 01:29:12

标签: bash

我有一个生成随机文件名的功能

#generate random file names
get_rand_filename() {
  if [ "$ASCIIONLY" == "1" ]; then
    for ((i=0; i<$((MINFILENAMELEN+RANDOM%MAXFILENAMELEN)); i++)) {
      printf \\$(printf '%03o' ${AARR[RANDOM%aarrcount]});
    }
  else
    # no need to escape double quotes for filename
    cat /dev/urandom | tr -dc '[ -~]' | tr -d '[$></~:`\\]' | head -c$((MINFILENAMELEN+RANDOM%MAXFILENAMELEN)) #| sed 's/\(["]\)/\\\1/g'
  fi
  printf "%s" $FILEEXT
}
export -f get_rand_filename

当我从另一个函数中调用

cf(){
              fD=$1
              echo "the target dir recieved is  " $fD

              CFILE="$(get_rand_filename)"
              echo "the file name is "$CFILE
}
export -f cf

当我打电话

echo "$targetdir" | xargs -0 sh -c 'cf $1' sh

我只得到FILEXT(没有随机文件名)

当我打电话

cf "$targetdir"

我得到一个有效的结果

我需要能够处理$ targetdir和文件名字符串中的空格。

1 个答案:

答案 0 :(得分:2)

echo "$targetdir" | xargs -0 sh -c 'cf $1' sh

您应该调用bash而不是sh。函数导出是一项bash功能。

$ foo() { echo bar; }
$ export -f foo
$ sh -c 'foo'
sh: 1: foo: not found
$ bash -c 'foo'
bar

此外,由于输入不是NUL分隔的,因此请摆脱-0选项。请改用-d'\n'。并引用"$1"以提高其健壮性。

echo "$targetdir" | xargs -d'\n' bash -c 'cf "$1"' bash

实际上,如果您更改输入格式,则可以使用-0

printf '%s\0' "$targetdir" | xargs -0 bash -c 'cf "$1"' bash

对于它的价值,mktemp创建随机的临时文件,并安全地执行。这样可以确保该文件尚不存在,然后创建该文件,以防止其他人在生成名称和将其返回给调用方之间的瞬间捕获该名称。