Nói rằng tôi có quá nhiều chương trình a
và b
tôi có thể chạy với ./a
và ./b
.
Có thể khác biệt đầu ra của họ mà không cần ghi vào tệp tạm thời?
Nói rằng tôi có quá nhiều chương trình a
và b
tôi có thể chạy với ./a
và ./b
.
Có thể khác biệt đầu ra của họ mà không cần ghi vào tệp tạm thời?
Câu trả lời:
Sử dụng <(command)
để chuyển đầu ra của một lệnh sang chương trình khác như thể đó là tên tệp. Bash chuyển đầu ra của chương trình sang một ống và truyền tên tệp như /dev/fd/63
cho lệnh bên ngoài.
diff <(./a) <(./b)
Tương tự như vậy bạn có thể sử dụng >(command)
nếu bạn muốn chuyển một cái gì đó thành một lệnh.
Điều này được gọi là "Thay thế quy trình" trong trang người đàn ông của Bash.
-bash: syntax error near unexpected token ('
. Tôi đã thử lại mà không có dấu ngoặc đơn và có -bash: java: No such file or directory
. Nó không hoạt động nếu lệnh có tham số?
alias diffcmd bash -c \'diff \<\(sh -c \!:1\) \<\( sh -c \!:2 \)\'
. (Sau đó, ví dụ: diffcmd "ls" "ls -a").
fseek
, zsh cung cấp =(./a)
có thể được sử dụng giống hệt <(./a)
nhưng sử dụng tệp tạm thời trong mui xe, zsh sẽ xóa cho bạn.)
Thêm vào cả hai câu trả lời, nếu bạn muốn xem so sánh cạnh nhau, hãy sử dụng vimdiff
:
vimdiff <(./a) <(./b)
Một cái gì đó như thế này:
vimdiff
tạo ra các quan điểm so sánh khác biệt đẹp, thông minh và tương tác. Nó dường như đi kèm với vim
gói trên hầu hết các hệ thống.
vimdiff
cũng cho thấy không chỉ dòng khác nhau mà cả đoạn văn bản cụ thể khác nhau.
Một lựa chọn sẽ là sử dụng các đường ống có tên (FIFO) :
mkfifo a_fifo b_fifo
./a > a_fifo &
./b > b_fifo &
diff a_fifo b_fifo
... nhưng giải pháp của John Kugelman sạch hơn nhiều.
rm a_fifo b_fifo
.
Đối với bất kỳ ai tò mò, đây là cách bạn thực hiện thay thế quy trình bằng cách sử dụng Vỏ cá :
Bash:
diff <(./a) <(./b)
Cá:
diff (./a | psub) (./b | psub)
Thật không may, việc thực hiện trên cá hiện đang thiếu ; cá sẽ treo hoặc sử dụng một tập tin tạm thời trên đĩa. Bạn cũng không thể sử dụng psub cho đầu ra từ lệnh của bạn.
Thêm một chút nữa vào các câu trả lời đã tốt (đã giúp tôi!):
Lệnh docker
xuất ra trợ giúp của nó STD_ERR
(tức là mô tả tệp 2)
Tôi muốn xem nếu docker attach
và docker attach --help
đưa ra cùng một đầu ra
$ docker attach
$ docker attach --help
Vừa gõ hai lệnh đó, tôi đã làm như sau:
$ diff <(!-2 2>&1) <(!! 2>&1)
!! giống như! -1 có nghĩa là chạy lệnh 1 trước lệnh này - lệnh cuối cùng
! -2 có nghĩa là chạy lệnh hai trước lệnh này
2> & 1 có nghĩa là gửi đầu ra file_descriptor 2 (STD_ERR) đến cùng một nơi với đầu ra file_descriptor 1 (STD_OUT)
Hy vọng điều này đã được sử dụng.
Đối với zsh, sử dụng =(command)
tự động tạo một tệp tạm thời và thay thế =(command)
bằng đường dẫn của chính tệp đó. Với Thay thế quy trình thông thường, $(command)
được thay thế bằng đầu ra của lệnh.
Tính năng zsh này rất hữu ích và có thể được sử dụng như vậy để so sánh đầu ra của hai lệnh bằng công cụ diff, ví dụ Beyond Beyond:
bcomp =(ulimit -Sa | sort) =(ulimit -Ha | sort)
Đối với Beyond So sánh, lưu ý rằng bạn phải sử dụng bcomp
cho mục đích trên (thay vì bcompare
) kể từ khi bcomp
khởi chạy so sánh và chờ đợi nó hoàn thành. Nếu bạn sử dụng bcompare
, nó sẽ khởi chạy so sánh và thoát ngay lập tức do các tệp tạm thời được tạo để lưu trữ đầu ra của các lệnh biến mất.
Đọc thêm tại đây: http://zsh.sourceforge.net/Intro/intro_7.html
Cũng lưu ý điều này:
Lưu ý rằng shell tạo một tệp tạm thời và xóa nó khi lệnh kết thúc.
và sau đây là sự khác biệt giữa $(...)
và =(...)
:
Nếu bạn đọc trang man của zsh, bạn có thể nhận thấy rằng <(...) là một hình thức thay thế quy trình khác tương tự như = (...). Có một sự khác biệt quan trọng giữa hai. Trong trường hợp <(...), shell tạo ra một ống có tên (FIFO) thay vì một tệp. Điều này là tốt hơn, vì nó không lấp đầy hệ thống tập tin; nhưng nó không hoạt động trong mọi trường hợp. Trên thực tế, nếu chúng ta đã thay thế = (...) bằng <(...) trong các ví dụ ở trên, tất cả chúng sẽ ngừng hoạt động ngoại trừ fgrep -f <(...). Bạn không thể chỉnh sửa đường ống hoặc mở nó dưới dạng thư mục thư; fgrep, tuy nhiên, không có vấn đề với việc đọc danh sách các từ từ một đường ống. Bạn có thể tự hỏi tại sao thanh diff <(foo) không hoạt động, vì foo | công trình khác biệt; điều này là do diff tạo một tệp tạm thời nếu nó thông báo rằng một trong các đối số của nó là - và sau đó sao chép đầu vào tiêu chuẩn của nó vào tệp tạm thời.