Ống gán biến


19

Để đơn giản, tôi muốn làm:

echo cart | assign spo;
echo $spo  

Đầu ra: giỏ hàng

Liệu một assignứng dụng như vậy tồn tại?

Tôi nhận thức được tất cả các cách để làm điều này bằng cách sử dụng thay thế.


Tại sao bạn muốn làm điều này mà không thay thế?
Thanatos

Tôi thích dòng ký hiệu Ba Lan ngược khi chỉ viết bằng ống. Tôi mã hóa nhanh hơn nhiều và chất lượng / tốc độ mã không quá quan trọng. Ngoài ra, tôi không khi xâu chuỗi, việc bình luận các phần của chuỗi sẽ dễ dàng hơn và lặp lại kết quả hiện tại thay vì xóa dấu
vết,

Nếu bạn lo ngại về việc dễ gỡ lỗi, hãy xem xét đưa lệnh backticks vào một loạt các dòng riêng biệt. A=$( some | command | here )với mỗi người trong some |, command |heretrên một dòng riêng.
roaima

Câu trả lời:


11
echo cart | { IFS= read -r spo; printf '%s\n' "$spo"; }

Sẽ hoạt động (lưu trữ đầu ra echomà không có ký tự dòng mới vào spobiến) miễn là echođầu ra chỉ có một dòng.

Bạn luôn có thể làm:

assign() {
  eval "$1=\$(cat; echo .); $1=\${$1%.}"
}
assign spo < <(echo cart)

Các giải pháp sau đây sẽ hoạt động trong bashcác tập lệnh, nhưng không phải tại bashdấu nhắc:

shopt -s lastpipe
echo cat | assign spo

Hoặc là:

shopt -s lastpipe
whatever | IFS= read -rd '' spo

Để lưu trữ đầu ra của whatevertối đa các ký tự NUL đầu tiên ( bashdù sao các biến cũng không thể lưu trữ các ký tự NUL) $spo.

Hoặc là:

shopt -s lastpipe
whatever | readarray -t spo

để lưu trữ đầu ra của whatevertrong $spo mảng (một dòng trên mỗi phần tử mảng).


1
không nên có một không gian giữa IFS=read?
caesarsol

Tất cả mưa đá cuối cùng. Ngoài ra bộ ghi chú bên + m (ermmm hoặc -m) là cần thiết từ một dòng lệnh cô ấy sẽ làm vì đường ống cuối cùng không hoạt động với hoạt động kiểm soát công việc.
MageProspero

17

Bạn có thể làm một cái gì đó như thế này, nếu bạn sử dụng bash:

echo cart | while read spo; do echo $spo; done

Thật không may, biến "spo" sẽ không tồn tại bên ngoài vòng lặp while-do-do. Nếu bạn có thể nhận được những gì bạn muốn thực hiện trong vòng lặp while, điều đó sẽ hoạt động.

Bạn thực sự có thể làm gần như chính xác những gì bạn đã viết ở trên trong ATT ksh (không phải trong pdksh hoặc mksh) hoặc trong zsh tuyệt vời:

% echo cart | read spo
% echo $spo
cart

Vì vậy, một giải pháp khác sẽ là sử dụng ksh hoặc zsh.


1
Bạn có thể sử dụng coprocesses trong Korn Shell (ví dụ mksh): echo cart |& while read -p spo; do echo $spo; done(thực sự tốt hơn để sử dụng while IFS= read -p -r spo; do…)
mirabilos

2

Nếu tôi hiểu vấn đề một cách chính xác, bạn muốn chuyển stdout sang một biến. Ít nhất đó là những gì tôi đang tìm kiếm và kết thúc ở đây. Vì vậy, đối với những người chia sẻ số phận của tôi:

spa=$(echo cart)

Gán cartcho biến $spa.


2
Đó là điều họ gọi là sự thay thế, điều mà OP muốn tránh.
Dmitry Grigoryev

Điều này rất hữu ích với tôi, tôi chỉ cần gán nó cho một biến, tôi không quan tâm làm thế nào nó đến đó!
Chris Marisic

1

Nếu bạn chỉ muốn đầu ra sử dụng luồng ống hiện tại cat.

echo cart | cat 

Nếu bạn muốn tiếp tục chuỗi lệnh của mình, hãy thử sử dụng teelệnh để lặp lại đầu ra.

echo cart | tee /dev/tty | xargs ls

Bạn có thể sử dụng một bí danh để rút ngắn lệnh.

alias tout='tee /dev/tty'
echo cart | tout | xargs ls

Tại sao bạn muốn đầu ra đường ống đến một đồng bằng cat?
roaima

1
@roaima Một số lệnh nhận ra chúng đang chạy trên thiết bị đầu cuối, hành vi khác với khi chúng xuất ra một đường ống. Cụ thể, họ có thể cắt các dòng theo chiều rộng màn hình hiện tại. Đối với hầu hết các lệnh, lệnh cat là dư thừa.
BillThor

Ah ok, tôi thấy bây giờ những gì bạn đang cố gắng minh họa. Công echo | cattrình đã ném tôi.
roaima

1

Đây là giải pháp của tôi cho vấn đề.

# assign will take last line of stdout and create an environment variable from it
# notes: a.) we avoid functions so that we can write to the current environment
#        b.) aliases don't take arguments, but we write this so that the "argument" appears
#            behind the alias, making it appear as though it is taking one, which in turn
#            becomes an actual argument into the temporary script T2.
# example: echo hello world | assign x && echo %x outputs "hello world"
alias assign="tail -1|tee _T1>/dev/null&&printf \"export \\\$1=\$(cat _T1)\nrm _T*\">_T2&&. _T2"
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.