Как я могу использовать `< <(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
3 метода стилизации элементов HTML
3 метода стилизации элементов HTML
Когда дело доходит до применения какого-либо стиля к нашему HTML, существует три подхода: встроенный, внутренний и внешний. Предпочтительным обычно...
Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Будучи разработчиком веб-приложений, легко впасть в заблуждение, считая, что приложение без JavaScript не имеет права на жизнь. Нам становится удобно...
Flatpickr: простой модуль календаря для вашего приложения на React
Flatpickr: простой модуль календаря для вашего приложения на React
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей....
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Клиент для URL-адресов, cURL, позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
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

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