Я предполагаю, что 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 (что позволяет избежать необходимости использования именованных каналов).