Как я могу использовать строки замены процесса в BASH? - PullRequest
0 голосов
/ 18 декабря 2018

Я знаю, что могу сделать что-то вроде

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.

Ответы [ 2 ]

0 голосов
/ 18 декабря 2018

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

0 голосов
/ 18 декабря 2018

Используйте именованные каналы напрямую.Используйте mktemp для создания временных имен файлов для каждого канала, чтобы вы могли удалить их после того, как закончите.

fifos=()
for f in file1 file2 file3; do
    t=$(mktemp)
    mkfifo "$t"
    pipes+=("$t")
    someCommand "$f" > "$t" &
done

someOtherCommand "${pipes[@]}"
rm "${pipes[@]}"
...