Вы можете просто использовать подстановку процессов непосредственно в перенаправлениях:
gen > >(one) 2> >(two)
Это даст стандартный вывод gen
в качестве стандартного ввода для one
и стандартную ошибку gen
в качестве ввода для two
. Это могут быть исполняемые команды или функции; вот функции, которые я использовал:
one() {
while read line
do
echo $'\e[31m'"$line"$'\e[22m'
done
}
two() {
while read line
do
echo $'\e[32m'"$line"$'\e[22m'
echo "$line" >&2
done
}
Они выводят свои входные строки красным и зеленым цветом соответственно, а two
также записывают с обычной стандартной ошибкой. Вы можете делать все, что хотите, внутри циклов или отправлять ввод в другую программу или что угодно.
Обратите внимание, что на самом деле не существует такой вещи, как "сохранение порядка строк", когда вы находитесь в этой точке-это два отдельных потока и отдельных процесса, и вполне возможно, что планировщик запускает один процесс некоторое время, прежде чем он даст другой ход, с данными, хранящимися в буфере канала ядра, пока они не будут прочитаны. Я использую функцию, выводящую нечетные числа на стандартный вывод и даже на стандартный вывод для тестирования, и обычно получается дюжина или более подряд из каждого.
Можно было бы получить что-то более близкое к порядку, как он появляется в терминале, но, вероятно, не в Bash. Программа на языке C, использующаяpipe
и select
, может восстановить порядок (, хотя не гарантируется, что он будет таким же, как показано,по той же причине :ваш процесс может какое-то время не планироваться, а когда возникает отставание, невозможно сказать, что было раньше 1). Если порядок жизненно важен, вам понадобится другой подход и, вероятно, сотрудничество с базовым исполняемым файлом. Если это сложное требование, вам, возможно, придется пересмотреть свое решение.
1Также могут существовать специфические для платформы -методы управления буферизацией канала, но вряд ли они помогут вам в достаточной мере. В Linux вы можете уменьшить размер буфера до размера системной страницы, но не меньше. Я не знаю ни одного, который позволяет принудительно выполнять запись немедленно (или блокировать до тех пор, пока они не будут прочитаны ). В любом случае, они вполне могут быть буферизованы на исходном конце подобно потокам stdio, и тогда вы никогда не увидите порядка.
What does "action" mean in " curl selects which methods to use on its own depending on what action to ask for"?
См. раздел о протоколе HTTP , который «определяет» термин:
HTTP is plain ASCII text lines being sent by the client to a server to request a particular action, and then the server replies a few text lines before the actual requested content is sent to the client.
Действие — это запрос HTTP-сервера :получение данных (, которые соответствуют методу GET
), добавление ресурса (метод PUT
), отправка данные в существующий ресурс (метод POST
)и т. д.
Isn't how a server handles a request what matters? Doesn't that only depend on what is written into the request message, and therefore on "the method keyword curl selects"?
Да, но общее отправляемое сообщение должно соответствовать ожиданиям, установленным выбранным методом. В вашем примере показано, что это:curl
создает допустимое сообщение для метода GET
, но вы переопределяете его, чтобы указать метод POST
, и сконструированное сообщение недействительно для POST
, что заставляет сервер отвечать ошибка.
Параметр -X
переопределяет метод без изменения поведения окружения.
What does "action" mean in " curl selects which methods to use on its own depending on what action to ask for"?
Я думаю, это относится к различным параметрам, которые изменяют то, что делает curl. Не похоже, чтобы они были явно названы «действиями» на странице руководства, но если они говорят «Запросы X с использованием метода FOO», то, похоже, это применимо. -I
/ --head
запрашивает только заголовки, поэтому он использует HEAD
, --data
использует POST
и --data --get
использует GET
. Обратите внимание, что цитируемый текст явно относится к -I
и -d
сразу после выделенной жирным шрифтом части.
Эта последняя пара важна, с GET
данные отправляются вместе с URL-адресом, то есть ...?data_here
, с POST
они отправляются как содержимое HTTP-запроса
С curl --data foo=bar http://host/path/to/foo.pl
получаем
POST /path/to/foo.pl HTTP/1.1
Content-Length: 7
Content-Type: application/x-www-form-urlencoded
foo=bar
и сcurl --data foo=bar --get http://host/path/to/foo.pl
GET /path/to/foo.pl?foo=bar HTTP/1.1
What does it mean by "If you use the --request / -X option" you can change the method keyword curl selects, but you will not modify curl's behavior.
Использование -X GET
не влияет на то, куда идут данные (или как они кодируются ). С --data foo=bar -X GET
curl
все еще думает, что выполняет POST
, поэтому отправляет данные в тело запроса, просто переименовывая метод (ниже ). Это, вероятно, не будет работать здесь, но было бы с -X XYZ
, если бы XYZ
был методом, который ожидал данные в теле запроса, такие как POST
.
GET /path/to/foo.pl HTTP/1.1
Content-Length: 7
Content-Type: application/x-www-form-urlencoded
foo=bar