Câu trả lời:
Tại sao lệnh thứ hai xuất ra một giá trị khác nhau?
Vì lý do lịch sử, dd
coi x
là một toán tử nhân. Vì vậy, 0x3
được đánh giá là 0.
Có thể vượt qua bỏ qua | tìm kiếm offset cho dd dưới dạng giá trị thập lục phân không?
Không trực tiếp, theo như tôi biết. Cũng như phép nhân bằng cách sử dụng toán tử x
, bạn có thể thêm bất kỳ số nào có b
nghĩa là "nhân với 512" (0x200) và với K
nghĩa là "nhân với 1024" (0x400). Với GNU dd bạn cũng có thể sử dụng hậu tố M
, G
, T
, P
, E
, Z
và Y
có nghĩa là nhân với 2 với sức mạnh của 20, 30, 40, 50, 60, 70, 80 hoặc 90, tương ứng, và bạn có thể sử dụng trên hoặc thấp hơn trường hợp ngoại trừ cho b
hậu tố. (Có nhiều hậu tố có thể khác. Ví dụ: EB
có nghĩa là "nhân với 10 18 " và PiB
có nghĩa là "nhân với 2 50 ". Xem info coreutils "block size"
thêm thông tin, nếu bạn có cài đặt GNU.)
Bạn có thể tìm thấy những điều phức tạp ở trên, lỗi thời và táo tợn đến mức phi lý. Đừng lo lắng: bạn không cô đơn. May mắn thay, bạn chỉ có thể bỏ qua tất cả và sử dụng thay thế số học của shell của mình (bash và các shell tương thích Posix khác sẽ hoạt động, cũng như một số shell không Posix). Shell không hiểu các số thập lục phân và nó cho phép đầy đủ các toán tử số học được viết theo cách thông thường. Bạn chỉ cần bao quanh biểu thức với $((...))
:
# dd if=2013-Aug-uptime.csv bs=1 count=$((0x2B * 1024)) skip=$((0x37))
$((...))
sẽ không thay đổi bất cứ điều gì. Trường hợp duy nhất tôi có thể nghĩ về nơi trích dẫn sẽ làm bất cứ điều gì là nếu bạn có một cái gì đó như thế IFS=4
nhưng điều đó sẽ gây ra tất cả các loại hỗn loạn khác.
$((...))
. POSIX rõ ràng rằng việc mở rộng $((...))
có thể bị chia tách từ . Để lại bất kỳ mở rộng lệnh / số học / biến nào không được trích dẫn trong ngữ cảnh danh sách là toán tử split + global. Đặt IFS = 4 sẽ không gây ra tất cả các loại vấn đề nếu bạn không sử dụng toán tử split + global khi không cần / muốn và đặt IFS mỗi khi bạn cần toán tử split + global đó.
IFS
thành một cái gì đó bao gồm các chữ số, một cái gì đó tôi không tin là tôi đã từng làm, thì bạn sẽ cần phải trích dẫn. Có lẽ, nếu một người đang làm điều đó, người ta sẽ nhận thức được sự cần thiết, vì đó là điều khó có thể làm một cách tình cờ. Hoặc, ít nhất, đó hầu như không phải là điều tôi có thể làm, giai đoạn. Tôi không có ý nói cho bạn.
Tôi biết đây là một chủ đề cũ, nhưng vấn đề vẫn còn rõ ràng hơn bao giờ hết, đặc biệt là khi những kẻ ngốc như tôi đi và vô tình nhớ lại và loại bỏ một 'cp fileA fileB' từ lịch sử bash khi fileB chưa được đăng ký để git không được sao lưu lên và chứa vài giờ mã hóa sau khi hoàn toàn sáng hơn: - /
Nhờ các khái niệm trong luồng này, tôi đã có thể khôi phục hoàn toàn tệp bị mất của mình, tuy nhiên tôi đã mất của tôi trên Máy chủ riêng ảo từ xa với đĩa 32Gb và rất ít RAM (chạy Ubuntu 18.04) và tất cả các ứng dụng của tôi sử dụng 'grep' như ở trên sẽ nhanh chóng chết với 'bộ nhớ không đủ'
Trong trường hợp của tôi, nó đã hexdump -C /dev/sdX1 | grep 'shortString'
đến để giải cứu tôi. Không giống như grep, nó chỉ hiển thị một đại diện ASCII rất kỳ diệu của hex, do đó, điều quan trọng là chỉ tìm kiếm một chuỗi duy nhất ngắn và lưu ý rằng thậm chí có thể được bọc. Khi nó đã xuất ra một số địa chỉ hex có khớp, tôi có thể sử dụng 'dd' theo cách tương tự như trên, ngoại trừ việc tôi thấy nó dường như được mặc định là kích thước khối 4096, vì vậy tôi không chỉ phải chuyển đổi địa chỉ byte hex thành số thập phân nhưng chia cho 4096 để chia tỷ lệ thành 4k khối cho tham số bỏ qua của dd - một cách vô ích, nếu con số này quá lớn đối với dd, thông báo lỗi có vẻ như skip=
không hợp lệ thay vì số được truyền cho nó .
Kudos cho những người đã thêm lời khuyên về việc sử dụng bash với $((0xabcd))
để giảm bớt sự phản đối hex-> dec convert :-)
Chỉ là từ cuối cùng của tôi - Trong trường hợp của tôi, có một vài bản sao của cùng một tệp gần nhau. Nhưng trừ đi địa chỉ thấp nhất từ địa chỉ cao nhất được báo cáo bởi hexdump, tôi có thể xác định vùng ~ 5 MB chứa tất cả các bản sao có thể, điều đó có nghĩa là tôi có thể nhắm mục tiêu dd ở địa chỉ thấp nhất và trích xuất toàn bộ vùng đó vào tệp tạm thời. Trình chỉnh sửa Vim hiện xử lý nội dung nhị phân khá duyên dáng để bạn có thể kiểm tra tempfile và định hình lại nó khi cần.
$((...))
là mở rộng số học POSIX, nó hoàn toàn không phải là bash cụ thể, bạn không phải sử dụngbash
để sử dụng nó, bất kỳ shell POSIX nào cũng được. Tuy nhiên, lưu ý rằng trong nhiều shell bao gồmbash
, nó trải qua quá trình phân tách từ nên được trích dẫn.