ไปป์กำหนดตัวแปร


19

เพื่อความเรียบง่ายฉันต้องการทำ:

echo cart | assign spo;
echo $spo  

เอาท์พุท: รถเข็น

มีassignแอปพลิเคชันดังกล่าวอยู่หรือไม่?

ฉันตระหนักถึงวิธีทั้งหมดในการทำเช่นนี้โดยใช้การทดแทน


ทำไมคุณต้องการทำสิ่งนี้โดยไม่มีการเปลี่ยนตัว?
Thanatos

ฉันชอบการไหลสัญกรณ์โปแลนด์ย้อนกลับเมื่อเขียนด้วยท่อเท่านั้น ฉันเขียนโค้ดได้เร็วขึ้นมากและคุณภาพ / ความเร็วของรหัสนั้นไม่สำคัญ นอกจากนี้ฉันไม่เมื่อผูกมัดมันเป็น hella ง่ายต่อการแสดงความคิดเห็นออกจากส่วนหนึ่งของห่วงโซ่และสะท้อนเอาท์พุทปัจจุบันค่อนข้างแล้วลบเห็บเป็นต้น
MageProspero

หากคุณกังวลเกี่ยวกับความสะดวกในการดีบักให้ลองวางคำสั่ง backticks ลงในชุดของบรรทัดที่แยกกัน A=$( some | command | here )กับแต่ละsome |, command |และhereในสายของตัวเอง
roaima

คำตอบ:


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

จะใช้งานได้ (เก็บผลลัพธ์echoโดยไม่มีอักขระบรรทัดใหม่ต่อท้ายลงในspoตัวแปร) ตราบใดที่echoเอาต์พุตเพียงหนึ่งบรรทัด

คุณสามารถทำได้:

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

วิธีแก้ไขปัญหาต่อไปนี้สามารถใช้งานได้กับbashสคริปต์ แต่ไม่แสดงbashพร้อมท์:

shopt -s lastpipe
echo cat | assign spo

หรือ:

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

ในการจัดเก็บการส่งออกของwhateverถึงตัวละคร NUL แรก ( bashตัวแปรที่ไม่สามารถเก็บอักขระ NUL อยู่แล้ว) $spoใน

หรือ:

shopt -s lastpipe
whatever | readarray -t spo

เพื่อเก็บผลลัพธ์whateverใน$spo อาร์เรย์ (หนึ่งบรรทัดต่อองค์ประกอบอาร์เรย์)


1
ไม่ควรมีช่องว่างระหว่างIFS=และread?
caesarsol

ทุกลูกเห็บท่อสุดท้าย นอกจากนี้ยังต้องมีการตั้งค่าหมายเหตุด้าน + m (ermmm หรือ -m) จากบรรทัดคำสั่งซึ่งจะทำให้ท่อสุดท้ายไม่ทำงานกับการควบคุมงานที่ใช้งานอยู่
MageProspero

17

คุณสามารถทำสิ่งนี้ถ้าคุณใช้bash:

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

น่าเสียดายที่ตัวแปร "spo" จะไม่มีอยู่นอกลูปขณะที่ต้องทำ หากคุณสามารถทำสิ่งที่คุณต้องการได้ในขณะที่ลูปจะทำงานได้

คุณสามารถทำสิ่งที่คุณเขียนไว้ด้านบนใน ATT ksh (ไม่ใช่ใน pdksh หรือ mksh) หรือใน zsh ที่เหลือเชื่อ:

% echo cart | read spo
% echo $spo
cart

ดังนั้นทางออกอื่นคือใช้ ksh หรือ zsh


1
คุณสามารถใช้ตัวประมวลผลร่วมใน Korn Shell (เช่นmksh): echo cart |& while read -p spo; do echo $spo; done(จริง ๆ แล้วควรใช้while IFS= read -p -r spo; do…)
mirabilos

2

ถ้าฉันเข้าใจปัญหาอย่างถูกต้องคุณต้องการไปป์ stdout ให้กับตัวแปร อย่างน้อยนั่นคือสิ่งที่ฉันกำลังมองหาและลงเอยที่นี่ ดังนั้นสำหรับผู้ที่แบ่งปันชะตากรรมของฉัน:

spa=$(echo cart)

กำหนดให้กับตัวแปรcart$spa


2
นั่นคือสิ่งที่พวกเขาเรียกการทดแทนซึ่ง OP ต้องการหลีกเลี่ยง
Dmitry Grigoryev

สิ่งนี้มีประโยชน์สำหรับฉันฉันแค่ต้องกำหนดมันให้กับตัวแปรฉันไม่สนใจว่ามันจะไปถึงที่นั่นได้อย่างไร!
Chris Marisic

1

catหากคุณเพียงแค่ต้องการที่จะส่งออกท่อใช้กระแสปัจจุบัน

echo cart | cat 

หากคุณต้องการที่จะดำเนินการต่อห่วงโซ่คำสั่งของคุณลองใช้teeคำสั่งเพื่อสะท้อนเอาท์พุท

echo cart | tee /dev/tty | xargs ls

คุณสามารถใช้นามแฝงเพื่อย่อคำสั่ง

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

ทำไมคุณต้องการที่จะส่งออกท่อไปยังที่ราบcat?
roaima

1
@roaima คำสั่งบางคนรับรู้ว่าพวกเขากำลังทำงานบน terminal ที่มีพฤติกรรมที่แตกต่างกว่าถ้าพวกเขาจะถูกส่งออกไปยังท่อ โดยเฉพาะอย่างยิ่งพวกเขาอาจตัดบรรทัดเป็นความกว้างของหน้าจอปัจจุบัน สำหรับคำสั่งส่วนใหญ่คำสั่ง cat ซ้ำซ้อน
BillThor

อ่าฉันเห็นแล้วว่าคุณกำลังพยายามอธิบายอะไรอยู่ สิ่งecho | catก่อสร้างทำให้ฉัน
roaima

1

นี่คือวิธีแก้ไขปัญหาของฉัน

# 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"
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.