我知道我可以做类似的事情
cat <(cat somefile)
但是我想建立一个<()
的字符串。
所以:
for file in *.file; do
mySubs="${mySubs} <(cat ${file})"
done
cat ${mySubs} #cat <(cat 1.file) <(cat 2.file) ... <(cat something.file)
无需使用eval
。
答案 0 :(得分:2)
直接使用命名管道。使用mktemp
为每个管道创建临时文件名,以便在完成操作后将其删除。
fifos=()
for f in file1 file2 file3; do
t=$(mktemp)
mkfifo "$t"
pipes+=("$t")
someCommand "$f" > "$t" &
done
someOtherCommand "${pipes[@]}"
rm "${pipes[@]}"
答案 1 :(得分:1)
我假设cat
是更复杂命令的替代者。在这里,我明确地包装它以显示:
#!/usr/bin/env bash
someCommand() { echo "Starting file $1"; cat "$1"; echo "Ending file $1"; }
wrap_all() {
## STAGE 1: Assemble the actual command we want to run
local fd cmd_len retval
local -a cmd fds fd_args
cmd_len=$1; shift
while (( cmd_len > 0 )); do
cmd+=( "$1" )
cmd_len=$((cmd_len - 1))
shift
done
## STAGE 2: Open an instance of someCommand for each remaining argument
local fd; local -a fds
fds=( )
for arg; do
exec {fd}< <(someCommand "$arg")
fds+=( "$fd" )
fd_args+=( "/dev/fd/$fd" )
done
## STAGE 3: Actually run the command
"${cmd[@]}" "${fd_args[@]}"; retval=$?
## STAGE 4: Close all the file descriptors
for fd in "${fds[@]}"; do
exec {fd}>&-
done
return "$retval"
}
调用方式:
echo "one" >one.txt; echo "two" >two.txt
wrap_all 1 cat one.txt two.txt
...输出:
Starting file one.txt
one
Ending file one.txt
Starting file two.txt
two
Ending file two.txt
请注意,这需要bash 4.1来支持自动FD分配(让我们避免使用命名管道)。