Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/211.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
Shell 使用xargs-P时如何将代码提取到函数中?_Shell_Sh_Xargs - Fatal编程技术网

Shell 使用xargs-P时如何将代码提取到函数中?

Shell 使用xargs-P时如何将代码提取到函数中?,shell,sh,xargs,Shell,Sh,Xargs,首先,我已经编写了代码,并且运行良好 # version1 all_num=10 thread_num=5 a=$(date +%H%M%S) seq 1 ${all_num} | xargs -n 1 -I {} -P ${thread_num} sh -c 'echo abc{}' b=$(date +%H%M%S) echo -e "startTime:\t$a" echo -e "endTime:\t$b" 现在我想将代码提取到一个函数中

首先,我已经编写了代码,并且运行良好

# version1
all_num=10
thread_num=5 
a=$(date +%H%M%S) 
seq 1 ${all_num} | xargs -n 1 -I {} -P ${thread_num} sh -c 'echo abc{}' 
b=$(date +%H%M%S) 
echo -e "startTime:\t$a"
echo -e "endTime:\t$b"
现在我想将代码提取到一个函数中,但它是错误的,如何修复它

get_file(i){
echo "abc"+i
 } 
all_num=10
thread_num=5 
a=$(date +%H%M%S) 
seq 1 ${all_num} | xargs -n 1 -I {} -P ${thread_num} sh -c "$(get_file {})"
b=$(date +%H%M%S) 
echo -e "startTime:\t$a"
echo -e "endTime:\t$b"

由于
/bin/sh
不能保证支持打印定义函数的文本,也不能通过环境导出函数,因此我们需要以艰难的方式完成这项工作,只需在xargs启动的
sh
副本中复制函数的文本即可

本站点中已经存在其他问题,描述了如何使用bash实现这一点,这相当容易。见f/e


注:

  • echo-e
    不能保证与
    /bin/sh
    一起使用。此外,为了使shell真正兼容,需要将
    -e
    写入其输出。请参见的和的应用程序使用部分
  • {}
    放在
    sh-c'.{}…'
    的位置是一个非常糟糕的主意。考虑在一个文件名中传递的情况,该文件名包含“代码> $(RM -Rf~)”$(RM- Rf~)'/COD>——它不能被安全地插入到未引用的上下文中,或双引号上下文,或单个引用的上下文,或遗传。< /LI>
  • 请注意,
    seq
    也是非标准的,不保证在所有符合POSIX的系统上都存在<代码>i=0;而[“$i”-lt“$all_num”];做回显“$i”;i=$((i+1));完成是一种可用于所有POSIX系统的替代方案

永远不要将
-I{}
sh-c'{}…'
组合使用--在这条道路上存在shell注入漏洞。让xargs将内容添加到shell的参数列表中,默认情况下不使用
-I
,并编写脚本来迭代这些参数。顺便问一下,您真的需要
/bin/sh
?使用bash会容易得多。@KamilCuk,不,argdo的
实际上是兼容POSIX的。我自己也弄错了,几年前这里有人用规范的链接纠正了我。哦,真的吗?啊,我的天。那么,我有一些规格阅读要做!谢谢$(date+%H%M%S)#警告:这真的很低效,有什么有效的方法@CharlesDuffy@flower,嗯,对于
/bin/sh
没有有效的方法,但是对于bash,
printf-va%%(%H%M%S)T'-1
是内置的等价于
a=$(date+%H%M%S)
@KamilCuk,我不得不去查阅它以刷新我的记忆——在语法中,请参见第一个选项,
for_子句:for name do_group
——尽管从当前规范版本来看,
for name sequential_sep do_group
同样有效,因此符合2018版本(至少)的shell必须接受
for arg;即使在
中没有
,也要执行
#!/bin/sh

all_num=10
thread_num=5 
batch_size=1  # but with a larger all_num, turn this up to start fewer copies of sh

a=$(date +%H%M%S) # warning: this is really inefficient
seq 1 ${all_num} | xargs -n "${batch_size}" -P "${thread_num}" sh -c '
  get_file() { i=$1; echo "abc ${i}"; }
  for arg do
    get_file "$arg"
  done
' _
b=$(date +%H%M%S)

printf 'startTime:\t%s\n' "$a"
printf 'endTime:\t%s\n' "$b"