Как я могу использовать `< <(tail ...)` в sh вместо bash?

Я хочу создать скрипт для чтения файла .txt. Это мой код:

while IFS= read -r lines
do
  echo "$lines"
done < <(tail -n +2 filename.txt)

Я пробовал много вещей, таких как:

<<(tail -n +2 in.txt)
< < (tail -n +2 in.txt)
< (tail -n +2 in.txt)
<(tail -n +2 in.txt)
(tail -n +2 in.txt)

Я ожидал напечатать меня со второй строки, но вместо этого получаю сообщение об ошибке:

Syntax error: redirection unexpected

Это сработает, если вы запустите его с Bash. Замена процесса не является функцией POSIX.

Arkadiusz Drabczyk 22.05.2019 13:12

я знаю, что если я запущу его как bash, он будет работать, но я должен написать его в sh, есть ли способ?

F_Stain 22.05.2019 13:18

смотри мой ответ ниже

Arkadiusz Drabczyk 22.05.2019 13:19

Если вы не возражаете против подоболочки, вы можете использовать tail … | while ….

Biffen 22.05.2019 13:19

Это не имеет ничего общего с tail, и все, что связано с синтаксисом замены процесса.

Charles Duffy 22.05.2019 13:24
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
5
746
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Как говорится в этом ответе Оболочка POSIX эквивалентна <() вы можете использовать именованные каналы для имитации замены процесса в POSIX. Ваш скрипт будет выглядеть так:

#!/usr/bin/env sh

mkfifo foo.fifo

tail -n +2 filename.txt >foo.fifo &

while IFS= read -r lines
do
    echo "$lines"
done < foo.fifo

rm foo.fifo

Как вы видите, что этот вопрос не является прямым дубликатом этого вопроса? Это не вызывает вопросов, связанных с tail; это просто спрашивает то же самое (как использовать подстановку процесса в sh) более расплывчато, без выполнения домашнего задания по знанию терминологии.

Charles Duffy 22.05.2019 13:25

Теперь, когда вы говорите это, я также думаю, что это дубликат. Я не думал об этом как о дубликате, потому что OP даже не знает, почему его сценарий не работает, он не сказал, что у него проблемы с заменой процессов.

Arkadiusz Drabczyk 22.05.2019 13:27
Ответ принят как подходящий

Если вы просто хотите проигнорировать первую строку, нет никакой веской причины использовать tail вообще!

{
    read -r first_line
    while IFS= read -r line; do
      printf '%s\n' "$line"
    done
} <filename.txt

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


Если вы сделал хотите использовать tail, для конкретного поднятого случая вам не нужно использовать подстановку процесса (<(...)), вы можете просто подключиться к вашему циклу while. Обратите внимание, что это имеет серьезный побочный эффект, поскольку любые переменные, которые вы устанавливаете в цикле, больше не будут доступны после его выхода; это задокументировано (в кросс-оболочке) в БашFAQ #24.

tail -n +2 filename.txt | while IFS= read -r line
do
  printf '%s\n' "$line"
done

Другие вопросы по теме