วิธีบันทึกเอาต์พุตจากคำสั่ง (เช่น. diff) ลงในตัวแปร


21

ฉันต้องการที่จะทดสอบว่ามีผลใด ๆ จากdiff(ทดสอบว่าไฟล์จะเหมือนกัน) echo "Passed $x" else echo "Failed $x"ถ้าไม่มี ฉันมาพร้อมกับขั้นตอน intermidiate (บันทึกผลลัพธ์จาก diff ไปยังไฟล์จากนั้นอ่านจากไฟล์)

diff "./helloworld$x.out" "./output/helloworld$x.out" > tmp.txt;
output="`cat tmp.txt`";

if [ "$output" = "" ];
  then
    echo "Passed $x";
  else
    echo "Failed $x";
  fi;

ฉันแน่ใจว่าสามารถปรับปรุงรหัสได้หรือไม่ คำถามหลักคือ: เป็นไปได้หรือไม่ที่จะบันทึกผลลัพธ์จากdiffตัวแปรโดยตรงหรือไม่?

คำตอบ:


18

งานนี้:

if diff "./helloworld$x.out" "./output/helloworld$x.out"> / dev / null; แล้วก็
    echo "ผ่าน $ x";
อื่น
    echo "ล้มเหลว $ x";
Fi

หากคุณใช้ตัวแปรแทนคุณechoสามารถปล่อยelsebranche: ตั้งค่าตัวแปรเป็นเท็จก่อนหน้าifและบันทึกรหัส 2 บรรทัด

หากคุณต้องการใส่ผลลัพธ์ลงในการใช้ตัวแปร:

some_var="$(diff "./helloworld$x.out" "./output/helloworld$x.out")"

รวมถึงการทดสอบของฉันเพื่อดูว่ามันใช้งานได้จริงหรือไม่:

rinzwind @ discworld: ~ $ touch 1
rinzwind @ discworld: ~ $ touch 2
rinzwind @ discworld: ~ ทดสอบเพิ่มอีก $
if diff 1 2> / dev / null; แล้วก็
    echo "ผ่าน $ x";
อื่น
    echo "ล้มเหลว $ x";
Fi
rinzwind @ discworld: ~ $ ./test
ผ่าน 

rinzwind @ discworld: ~ $ vi 2
rinzwind @ discworld: ~ $ มากกว่า 2
2
rinzwind @ discworld: ~ $ ./test
ล้มเหลว 

ใน>/dev/nullส่วน: >/dev/null 2>&1จะส่งออกไป>/dev/nullและ2>&1 จะส่งข้อผิดพลาดมาตรฐานไปยังไฟล์เดียวกัน ( &1หมายถึง 'ใช้พารามิเตอร์แรก') ในด้านหน้าของคำสั่งนี้ (ดังนั้นจึงยังใช้/dev/null)

sdiffด้านข้าง: จะแสดงdiffรายชื่อเคียงข้างกัน:

sdiff 1 2 
1 1
2 2
3 3
4 4
5 5
7 7
                                  > 8
9 9
10 10

ขอบคุณมันใช้งานได้ แต่ฉันไม่เข้าใจสิ่งที่... > /dev/nullเกิดขึ้นในบริบทนี้ ผลลัพธ์ของ diff จะเป็น goto / dev / null แต่ไม่ใช่ว่าอะไร?
Jiew Meng

1
diff จะแสดงผลต่างทั้งหมดระหว่างไฟล์บนหน้าจอของคุณและ> / dev / null ทำให้แน่ใจว่าผลลัพธ์ของคำสั่งถูกเปลี่ยนเส้นทางไปยังการให้อภัย ถ้ายังคงดำเนินการตามเอาท์พุท
Rinzwind

1
คำสั่ง if ตรวจสอบโค้ดทางออกของคำสั่ง diff 0 หมายถึงไม่พบความแตกต่างในขณะที่ 1 หมายถึงมีความแตกต่างอย่างน้อยหนึ่งรายการ
Knut Eldhuset

17

diff สามารถระงับเอาต์พุตได้อย่างสมบูรณ์ยกเว้นข้อความ "Files / bin / bash และ / bin / sh แตกต่าง" โดยใช้รหัสด้านล่าง

file1="./helloworld$x.out"
file2="./output/helloworld$x.out"

if diff -q "$file1" "$file2"; then
    echo "Passed $x"
else
    echo "Failed $x"
fi

หากคุณต้องการซ่อนข้อความนั้นคุณจะต้องต่อท้าย> /dev/nullคำสั่ง diff เพื่อซ่อนผลลัพธ์ของdiff:

if diff -q "$file1" "$file2" >/dev/null; then

/dev/null เป็นไฟล์พิเศษที่ทำหน้าที่เป็น blackhole ถ้าคุณเขียนลงไปมันจะหายไปถ้าคุณอ่านจากมันคุณจะไม่ได้อะไรเลย

โปรดทราบว่า bash ไม่จำเป็นต้อง;จบบรรทัด

สำหรับคำถามเดิมการบันทึกผลลัพธ์ของโปรแกรมในตัวแปร:

file1="./helloworld$x.out"
file2="./output/helloworld$x.out"
output="$(diff -q "$file1" "$file2")"

# the quotes are mandatory, this checks whether $output is empty or not
if [ -n "$output" ]; then
    echo "Passed $x"
else
    echo "Failed $x"
fi

วิธีอื่นในการตรวจสอบว่าตัวแปรว่างเปล่าหรือไม่:

[ "$output" = "" ]
[ "$output" == "" ]
[[ "$output" == "" ]]
[[ $output == "" ]]

หากคุณใช้ Bash คำแนะนำสองคำสั่งสุดท้ายสำหรับการเปรียบเทียบสตริง มิฉะนั้นคนแรกและ[ -n "$output" ]ขอแนะนำ


6

ก) เอาต์พุตของ command1 สามารถจับได้ด้วย

output=$(diff "helloworld$x.out" "output/helloworld$x.out") 

หรือกับ backticks แต่สิ่งเหล่านี้เป็นสิ่งที่ท้อใจเพราะคุณไม่สามารถซ้อนมันและพวกมันอาจแยกความแตกต่างจาก apostrophs ได้ยากขึ้นอยู่กับตัวอักษร:

 output=`cmd1`

b) แทนที่จะเขียนไปยังไฟล์แล้วอ่านไฟล์นั้น (หรือหยิบเอาท์พุทแล้วสะท้อนออกมา) คุณควรใช้ไพพ์โดยตรง:

 cmd1 > file
 cat file | cmd2 

 output=$(cmd1)
 echo "${output}" | cmd2 

=>

 cmd1 | cmd2 

แต่ในตัวอย่างของคุณคุณไม่สนใจผลลัพธ์ แต่ผลลัพธ์ของโปรแกรม - ใช้งานได้จริงหรือ

 diff "helloworld$x.out" "output/helloworld$x.out" && echo "success" || echo "failure" 

หากต้องการอ่านเกี่ยวกับการใช้ && และ || ค้นหา "ทางลัดและทางลัดหรือ"

เพื่อรักษาความสะอาดเอาท์พุทคุณสามารถเปลี่ยนทิศทางของ 'diff' ไปที่ใดก็ได้:

 diff "helloworld$x.out" "output/helloworld$x.out" >/dev/null && echo "success" || echo "failure" 

เพื่อคว้าความสำเร็จและประเมินผลในภายหลังคุณเก็บผลลัพธ์ของคำสั่งสุดท้ายในตัวแปรด้วย $ ?:

diff "helloworld$x.out" "output/helloworld$x.out" >/dev/null
result=$?
# do something else
case $result in 
   0) echo success ;;
   *) echo failure ;;
esac

3

หากคุณต้องการทราบว่าไฟล์สองไฟล์เหมือนกันหรือแตกต่างกัน (แต่ไม่สนใจว่าความแตกต่างคืออะไร) cmpจะเหมาะสมกว่า

if cmp -s file1 file2; then echo "Equal"; else echo "Not equal"; fi
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.