ผ่าน dd skip | หา offset เป็นเลขฐานสิบหก


11
# dd if=2013-Aug-uptime.csv bs=1 count=1 skip=3 2> /dev/null
d
# dd if=2013-Aug-uptime.csv bs=1 count=1 skip=0x3 2> /dev/null
f

ทำไมคำสั่งที่สองให้ผลลัพธ์ที่แตกต่างกัน?

เป็นไปได้ไหมที่จะผ่านการข้าม | แสวงหาการชดเชยให้ddเป็นค่าเลขฐานสิบหก?

คำตอบ:


18

ทำไมคำสั่งที่สองให้ผลลัพธ์ที่แตกต่างกัน?

ด้วยเหตุผลทางประวัติศาสตร์ddถือว่าxเป็นตัวดำเนินการคูณ ดังนั้น0x3ประเมินว่าเป็น 0

เป็นไปได้ไหมที่จะผ่านการข้าม | หาค่า offset ไปยัง dd เป็นค่าเลขฐานสิบหก?

ไม่โดยตรงเท่าที่ฉันรู้ เช่นเดียวกับการคูณโดยใช้โอเปอเรเตอร์xคุณสามารถต่อท้ายหมายเลขใด ๆ ด้วยbการหมายถึง "คูณด้วย 512" (0x200) และด้วยKการหมายถึง "คูณด้วย 1024" (0x400) ด้วย GNU dd คุณยังสามารถใช้ต่อท้ายM, G, T, P, E, ZและYหมายถึงคูณด้วย 2 ถึงพลังของ 20, 30, 40, 50, 60, 70, 80 หรือ 90 ตามลำดับและคุณสามารถใช้บนหรือล่างกรณียกเว้น สำหรับbคำต่อท้าย (มีคำต่อท้ายที่เป็นไปได้อื่น ๆ อีกมากมายตัวอย่างเช่นEBหมายถึง "คูณด้วย 10 18 " และPiBหมายถึง "คูณด้วย 2 50 " ดูinfo coreutils "block size"ข้อมูลเพิ่มเติมหากคุณมีการติดตั้ง GNU)

คุณอาจพบความลับข้างต้นสมัยและเกินบรรยายถึงจุดที่ไร้สาระ ไม่ต้องกังวล: คุณไม่ได้อยู่คนเดียว โชคดีที่คุณสามารถละเว้นได้ทั้งหมดและใช้การทดแทนทางคณิตศาสตร์ของเชลล์แทน (bash และเชลล์ที่เข้ากันได้กับ Posix อื่น ๆ จะทำงานได้เช่นเดียวกับเชลล์ที่ไม่ใช่ Posix) เชลล์เข้าใจตัวเลขฐานสิบหกและอนุญาตให้ผู้ดำเนินการทางคณิตศาสตร์เต็มรูปแบบเขียนตามปกติ คุณเพียงแค่ต้องล้อมรอบการแสดงออกด้วย$((...)):

# dd if=2013-Aug-uptime.csv bs=1 count=$((0x2B * 1024)) skip=$((0x37))

โปรดทราบว่านั่น$((...))คือการขยายตัวทางคณิตศาสตร์ POSIX มันไม่ได้ทุบตีเฉพาะเลยคุณไม่จำเป็นต้องใช้bashเพื่อใช้งานเชลล์ POSIX ใด ๆ จะทำเช่นนั้น อย่างไรก็ตามโปรดทราบว่าในหลาย ๆ เชลล์รวมถึงbashมันจะผ่านการแยกคำดังนั้นควรจะยกมา
Stéphane Chazelas

@StephaneChazelas: นั่นเป็นความจริงไม่ใช่เฉพาะทุบตี อย่างไรก็ตามไม่จำเป็นต้องมีเครื่องหมายคำพูด (Posix: "การแสดงออกจะต้องได้รับการปฏิบัติราวกับว่ามันอยู่ในเครื่องหมายคำพูดคู่ยกเว้นว่าการอ้างอิงสองครั้งภายในการแสดงออกไม่ได้รับการปฏิบัติเป็นพิเศษ") ถ้ามีตัวแปรในการแสดงออกและค่าของมันรวมถึงตัวคั่น แล้วมันจะไม่เป็นตัวเลขที่ถูกต้อง การใส่เครื่องหมายคำพูดรอบ ๆ$((...))จะไม่เปลี่ยนแปลงอะไรเลย กรณีเดียวที่ฉันสามารถคิดได้ว่าราคาจะทำอะไรถ้าคุณมีสิ่งที่ชอบIFS=4แต่ที่จะทำให้เกิดความสับสนวุ่นวายอื่น ๆ ทุกประเภท
rici

$((...))ส่วนที่คุณพูดเป็นเรื่องเกี่ยวกับสิ่งที่อยู่ภายใน POSIX เป็นที่ชัดเจนว่าการขยายตัวของ$((...))เป็นเรื่องที่แยกคำ การออกจากการขยายคำสั่ง / คณิตศาสตร์ / ตัวแปรใด ๆ ที่ไม่ได้กล่าวถึงในบริบทรายการคือตัวดำเนินการแยก + glob การตั้งค่า IFS = 4 จะไม่ก่อให้เกิดปัญหาทุกประเภทหากคุณไม่ได้ใช้ตัวแยก + glob ที่ไม่ต้องการ / ต้องการและตั้งค่า IFS ทุกครั้งที่คุณต้องการตัวดำเนินการแยก + glob
Stéphane Chazelas

@StephaneChazelas: ใช่ผลตัวเลขขึ้นอยู่กับการแยกคำ แต่มันเป็นจำนวนเต็ม หากคุณตั้งค่าIFSเป็นตัวเลขซึ่งมีบางสิ่งที่ฉันไม่เชื่อว่าฉันได้ทำไปแล้วคุณจะต้องพูด สันนิษฐานว่าหากมีใครทำอย่างนั้นเราจะต้องตระหนักถึงความต้องการเพราะมันแทบจะเป็นสิ่งที่คนเรามักจะทำแบบสบาย ๆ หรืออย่างน้อยมันก็เป็นสิ่งที่ไม่ค่อยน่าจะเป็นไปได้ ฉันไม่ได้ตั้งใจจะพูดเพื่อคุณ
rici

1
@ogurets: คุณใช้เชลล์อะไร? (โปรดระบุรุ่น)
rici

0

ฉันรู้ว่านี่เป็นเธรดเก่า แต่ปัญหายังคงเป็น revlevant เช่นเคยโดยเฉพาะอย่างยิ่งเมื่องี่เง่าเช่นฉันไปและเรียกคืนโดยไม่ตั้งใจและ excute 'cp fileA fileB' จากประวัติทุบตีเมื่อ fileB ยังไม่ได้เช็คอินเพื่อคอมไพล์ไม่ได้สำรอง ขึ้นและประกอบด้วยหลายชั่วโมงของการเข้ารหัสหลังจาก all-nighter: - /

ขอบคุณแนวคิดในหัวข้อนี้ฉันสามารถกู้คืนไฟล์ที่หายไปได้อย่างสมบูรณ์อย่างไรก็ตามฉันทำเหมืองบน Virtual Private Server ระยะไกลที่มีดิสก์ 32Gb และ RAM น้อยมาก (ใช้ Ubuntu 18.04) และ attemtps ของฉันทั้งหมดใช้ 'grep' เป็น ข้างต้นจะตายอย่างรวดเร็วด้วย 'หน่วยความจำไม่เพียงพอ'

ในกรณีของฉันมันhexdump -C /dev/sdX1 | grep 'shortString'มาเพื่อช่วยเหลือฉัน ซึ่งแตกต่างจาก grep มันแสดงเฉพาะการแทน ASCII narroy ของ hex ดังนั้นจึงเป็นสิ่งสำคัญที่จะมองหาเฉพาะสายสั้นที่ไม่ซ้ำกันและจำไว้ว่าแม้จะสามารถห่อ เมื่อมันมีเอาต์พุตเลขฐานสิบหกบางส่วนที่มีการแข่งขันฉันสามารถใช้ 'dd' ในรูปแบบที่คล้ายกันดังกล่าวข้างต้นยกเว้นว่าฉันพบว่ามันดูเหมือนว่าจะเริ่มต้นขนาดบล็อก 4096 ดังนั้นฉันไม่เพียงต้อง แปลงที่อยู่เลขฐานสิบหกเป็นทศนิยม แต่หารด้วย 4096 เพื่อปรับให้เป็น 4k บล็อกสำหรับพารามิเตอร์การข้ามของ dd - ไม่ช่วยถ้าหมายเลขนี้ใหญ่เกินไปสำหรับ dd ข้อความแสดงข้อผิดพลาดดูเหมือนว่ามันบ่นskip=ว่าไม่ถูกต้องมากกว่าจำนวนที่ส่งผ่านไป .

ความรุ่งโรจน์ของคนที่เพิ่มเคล็ดลับเกี่ยวกับการใช้ bash กับ$((0xabcd))เพื่อความสะดวก obtaion hex-> dec conversion :-)

คำสุดท้ายของฉัน - ในกรณีของฉันมีไฟล์เดียวกันหลายชุดซึ่งอยู่ใกล้กันทั้งหมด แต่การลบที่อยู่ต่ำสุดจากที่อยู่สูงสุดที่รายงานโดย hexdump ฉันสามารถระบุภูมิภาค ~ 5MB ที่มีสำเนาที่เป็นไปได้ทั้งหมดซึ่งหมายความว่าฉันสามารถกำหนดเป้าหมาย dd ที่ที่อยู่ต่ำสุดและแยกพื้นที่ทั้งหมดนั้นเป็นไฟล์ชั่วคราว โปรแกรมแก้ไข Vim ตอนนี้จัดการเนื้อหาไบนารีอย่างเป็นธรรมได้อย่างสวยงามดังนั้นคุณสามารถตรวจสอบ tempfile และปรับรูปร่างตามต้องการ

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