youtube-dl, как записать все подсети списка воспроизведения youtube в ОДИН один файл?

Пожалуйста, не могли бы вы предоставить iptables -t filter -nvL выходы на серверах B и C?

Я предполагаю, что канал autossh работает на сервере C. Так ли это? Если да, то я предлагаю другой подход. На B вам нужно правило REDIRECT, потому что ядро не позволит непривилегированному пользователю открыть порт 80.

iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 10000
iptables -t filter -A INPUT -p tcp --dport 10000 -j ACCEPT

(EDIT): На сервере B, GatewayPorts должен быть включен в /etc/ssh/sshd_config:

# /etc/ssh/sshd_config
GatewayPorts clientspecified

На сервере C, перенаправляйте соединения непосредственно на донгл, изменяя autossh аргументы:

autossh -M 0 -N user@myserver.dyndns.com -R 10022:127.0.0.1:22 \
    -R :10000:192.168.8.1:80

Единственная ошибка, которую я вижу в вашей установке, связана с правилом цепочки PREROUTING на сервере C. В этом сценарии оно не будет оцениваться, поскольку влияет только на пакеты, входящие через сетевые интерфейсы. Соединения, создаваемые ssh, генерируются локально, поэтому на них будут влиять правила в цепочке OUTPUT.

9
01.04.2019, 13:41
6 ответов

Попробуйте:

awk '{x=x $0 ORS}; END{printf "%s", $0 ORS x}'

Пример

Определить переменную с помощью нашего ввода:

$ input="line 1
> line 2
> line 3"

Запускаем нашу команду:

$ echo "$input" | awk '{x=x $0 ORS}; END{printf "%s", $0 ORS x}'
line 3
line 1
line 2
line 3

В качестве альтернативы, конечно, мы могли бы использовать здесь -doc:

$ cat <<EOS | awk '{x=x $0 ORS}; END{printf "%s", $0 ORS x}'
line 1
line 2
line 3
EOS
line 3
line 1
line 2
line 3

Как это работает

  • x=x $0 ORS

    Это добавляет каждую строку ввода к переменной x.

    В awk ORS— это разделитель выходных записей . По умолчанию это символ новой строки.

  • END{printf "%s", $0 ORS x}

    После того, как мы прочитали весь файл, выводится последняя строка $0, за которой следует содержимое всего файла x.

Так как это считывает весь ввод в память, это не подходит для больших (, например. гигабайт )входных данных.

7
27.01.2020, 20:05
cat <<EOS | sed -ne '1{h;d;}' -e 'H;${G;p;}'
line 1
line 2
line 3
EOS

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

  1. Предоставьте полное содержание документа tail.
  2. Предоставьте его еще раз по cat.
  3. Именно в таком порядке.

Хитрость заключается не в том, чтобы дублировать содержимое документа(teeделает это ), а в том, чтобы вывод tailпроисходил до вывода остальной части документа без использования промежуточного временного файла.

Использованиеsed(или awk, как это делает John1024,)избавляет от двойного разбора данных и проблемы упорядочения путем сохранения данных в памяти.

Решение, которое я предлагаю sedсостоит в том, чтобы

  1. 1{h;d;}, сохранить первую строку в ячейке удержания, как -, и перейти к следующей строке.
  2. H, добавляйте каждую другую строку в пространство для хранения со встроенным символом новой строки.
  3. ${G;p;}, добавьте пробел к последней строке со встроенной новой строкой и распечатайте полученные данные.

Это дословный перевод решения John1024 на sedс той оговоркой, что стандарт POSIX гарантирует только то, что пространство хранения составляет не менее 8192 байт (8 КиБ; но он рекомендует , чтобы этот буфер динамически выделялся и расширялся по мере необходимости, что и GNU sedи BSD sedделают ).


Если вы позволите себе использовать именованный канал:

mkfifo mypipe
cat <<EOS | tee mypipe | cat <( tail -n 1 mypipe ) -
line 1
line 2
line 3
EOS
rm -f mypipe

Используется teeдля отправки данных вниз mypipeи одновременно на cat. Утилита catсначала прочитает вывод из tail(, который считывается из mypipe, который teeзаписывает в ), а затем добавляет копию документа, поступающего непосредственно из tee.

Однако в этом есть серьезная ошибка: если документ слишком велик,(превышает размер буфера канала ), запись teeв mypipeи catбудет block, ожидая, пока (безымянный )канал опустеет. Он не будет опустошен, пока catне прочитает из него. catне будет читать из него, пока tailне закончит. И tailне закончится, пока teeне закончится. Это классическая тупиковая ситуация.

Вариация

tee >( tail -n 1 >mypipe ) | cat mypipe -

имеет ту же проблему.

4
27.01.2020, 20:05

Если вас не волнует порядок. Тогда это сработает cat lines | tee >(tail -1). Как сказали другие. Вам нужно прочитать файл дважды или буферизовать весь файл, чтобы сделать это в том порядке, в котором вы просили.

0
27.01.2020, 20:05

Если stdin указывает на доступный для поиска файл (, как в случае bash (, но не во всех других документах оболочки ), которые реализованы с помощью временных файлов ), вы можете получить хвост, а затем искать назад, прежде чем читать полное содержание:

операторы seek доступны в оболочках zshили ksh93или языках сценариев, таких как tcl/perl/python, но не в bash. Но вы всегда можете вызвать эти более продвинутые интерпретаторы из bash, если вам нужно использовать bash.

ksh93 -c 'tail -n1; cat <#((0))' <<...

Или

zsh -c 'zmodload zsh/system; tail -n1; sysseek 0; cat' <<...

Теперь это не будет работать, когда стандартный ввод указывает на -недоступные для поиска файлы, такие как канал или сокет. Тогда единственным вариантом является чтение и сохранение (в памяти или во временном файле... )всего ввода.

Некоторые решения для сохранения в памяти уже были даны.

С временным файлом, с zsh, вы можете сделать это с помощью:

seq 10 | zsh -c '{ cat =(sed \$w/dev/fd/3); } 3>&1'

Если в Linux с bashили zshили любой оболочкой, которая использует временные файлы для здесь -документов, вы можете фактически использовать временный файл, созданный здесь -документом, для хранения вывода :

. ]
seq 10 | {
  chmod u+w /dev/fd/3 # only needed in bash5+
  cat > /dev/fd/3
  tail -n1 /dev/fd/3
  cat <&3
} 3<<EOF
EOF
5
27.01.2020, 20:05

Существует инструмент с именем peeв наборе утилит командной строки -, обычно упакованных с именем «moreutils» (или иным образом загружаемых с его домашнего веб-сайта).

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

cat <<EOS | pee 'tail -1' cat 
line 1
line 2
line 3
EOS

Порядок выполнения команд через peeважен, поскольку они выполняются в заданной последовательности.

2
27.01.2020, 20:05

Попробуйте:

cat <<EOS # | what goes here now? Nothing!
line 3
line 1
line 2
line 3
EOS

Так как все это литеральные данные («здесь -есть документ» ), и разница между этим и желаемым результатом тривиальна, просто массируйте эти литеральные данные прямо здесь, чтобы они соответствовали выходным данным.

Теперь предположим, что line 3приходит откуда-то и хранится в переменной с именемlastline:

cat <<EOS # | what goes here now? Nothing!
$lastline
line 1
line 2
$lastline
EOS

В этом документе мы можем генерировать текст, подставляя переменные. Кроме того, мы можем вычислять текст, используя подстановку команд:

cat <<EOS
this is template text
here we have a hex conversion: $(printf "%x" 42)
EOS

Мы можем интерполировать несколько строк:

cat <<EOS
multi line
preamble
$(for x in 3 1 2 3; do echo line $x ; done)
epilog
EOS

В общем, избегайте обработки текста в шаблоне здесь документа; попробуйте сгенерировать его с помощью интерполированного кода.

1
27.01.2020, 20:05

Теги

Похожие вопросы