Они не то же самое с точки зрения Unix (или, скорее, с точки зрения оболочки).
https_proxy=http://myproxy.com/ aws [aws-param]
явно определяет переменную https_proxy
для команды aws
; оболочка копирует его в среду процесса aws
, и aws
видит его.
https_proxy=http://myproxy.com/
aws [aws-param]
определяет переменную в среде оболочки, но поскольку она не экспортируется, оболочка не копирует ее в среду процесса aws
.
Эквивалент (с точки зрения aws
) на самом деле
https_proxy=http://myproxy.com/
export https_proxy
aws [aws-param]
См. Что это за синтаксис Bash: someVariable = someValue command для получения дополнительных сведений (и ссылки на документация).
Если вы выполните один системный вызов read ()
в канале, он зависнет, если в канале ничего нет, но в противном случае немедленно вернуться с тем, что там.
Теперь, для , что там , с Linux 4.4 на моей многоядерной системе amd64 по крайней мере (YMMV с другими системами или другими версиями Linux), если один или несколько процессов в настоящее время выполняют write ()
(или другой системный вызов записи) на другом конце, возможно, больше, чем емкость канала (64 КБ по умолчанию в текущих версиях Linux), планировщик будет переключаться между этими процессами и одно чтение из канала несколько раз во время этого системного вызова read ()
и read ()
может вернуть гораздо больше, чем емкость канала.
Команда dd
- это интерфейс командной строки для системного вызова read
.
dd bs=1G count=1
(обратите внимание, что не все реализации dd
поддерживают эти суффиксы G
) делает ли один read ()
размером 1 ГБ со стандартного ввода (за которым следует один ] write ()
на стандартный вывод)
С помощью GNU dd
вы можете избежать блокировки на пустом канале с помощью iflag = nonblock
. Это устанавливает канал в неблокирующий режим, но учтите, что впоследствии он оставляет его неблокирующим, что может быть нежелательно.Например:
(date; sleep 2; date) |
(sleep 1
dd bs=1G count=1 status=none iflag=nonblock
wc -c)
give:
Mon 23 Jan 22:11:30 GMT 2017
wc: 'standard input': Resource temporarily unavailable
0
Поскольку канал также становится неблокирующим для wc
.
И как было сказано ранее, с неблокируемым
или без него, вы можете в конечном итоге прочитать больше, чем может поместиться в конвейер:
$ (cat /dev/zero & cat /dev/zero & cat /dev/zero) |
(sleep 1; dd bs=1G count=1) | wc -c
0+1 records in
0+1 records out
545914880 bytes (546 MB, 521 MiB) copied, 0.48251 s, 1.1 GB/s
545914880
(и вы будете получать разные числа от одного запуска к другому ).
Другой подход к системам, которые его поддерживают, заключается в использовании FIONREAD
ioctl ()
для запроса объема данных в конвейере перед выполнением чтения.
perl -e '
require "sys/ioctl.ph";
ioctl(STDIN, &FIONREAD, $n) or die "ioctl: $!\n";
$n = unpack "L", $n;
if ($n) {
sysread STDIN, $text, $n or die "read: $!\n";
print $text
}'
Обратите внимание, что, поскольку это выполняется в два этапа, если другой процесс одновременно читает из конвейера, он все равно может закончить блокировку, если этот другой процесс опустошает конвейер между ioctl ()
, а читается как ()
.
Вы можете использовать простую программу C для чтения из stdin
, записи в stdout
и выхода, фактически не дожидаясь EOF
, и использовать его как промежуточное звено в трубопроводной цепи.
Вот простой пример:
main.c
#include <stdio.h>
#include <unistd.h>
#define BUFFER_SIZE 1024
int main(int argc, char **argv){
char buffer[BUFFER_SIZE];
ssize_t read_size;
//Read up to BUFFER_SIZE bytes of what's currently at the stdin
read_size = read(STDIN_FILENO, buffer, BUFFER_SIZE);
if(read_size > 0){
write(STDOUT_FILENO, buffer, read_size);
}
return 0;
}
Скомпилируйте эту программу, используя gcc -o test main.c
.
Затем, если вы запустите {echo a; спать 2 секунды; эхо б; } | {спит 1 сек; ./тестовое задание; } | {./mycommand; }
, mycommand
получит только a
, поскольку это был единственный символ в stdin
при чтении ./ test
от него.
Чтобы проверить это, вы можете запустить {echo a; спать 2 секунды; эхо б; } | {спит 1 сек; ./тестовое задание; } | cat
, при котором на экране будет отображаться только a
.