Làm thế nào để tìm sự khác biệt giữa tệp script và tệp nhị phân?


11
$ ls -l /usr/bin
total 200732

-rwxr-xr-x 1 root   root     156344 Oct  4  2013 adb
-rwxr-xr-x 1 root   root       6123 Oct  8  2013 add-apt-repository
 list goes long ---------

Ở trên adblà tệp nhị phân và add-apt-repositorylà tệp script. Tôi có được thông tin này bằng cách xem các tệp qua nautilus. Nhưng thông qua dòng lệnh, tôi không tìm thấy bất kỳ sự khác biệt nào. Tôi không thể dự đoán liệu tệp là tệp nhị phân hay một tập tin kịch bản.

Vậy làm cách nào để phân biệt tập tin nhị phân và tập tin nhị phân thông qua dòng lệnh?

Câu trả lời:


16

Chỉ cần sử dụng file:

$ file /usr/bin/add-apt-repository
/usr/bin/add-apt-repository: Python script, ASCII text executable
$ file /usr/bin/ab
/usr/bin/ab: ELF 64-bit LSB  shared object, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=569314a9c4458e72e4ac66cb043e9a1fdf0b55b7, stripped

Như đã giải thích trong man file:

NAME
   file — determine file type

DESCRIPTION
 This manual page documents version 5.14 of the file command.

 file tests each argument in an attempt to classify it.  There are three
 sets of tests, performed in this order: filesystem tests, magic tests,
 and language tests.  The first test that succeeds causes the file type to
 be printed.

 The type printed will usually contain one of the words text (the file
 contains only printing characters and a few common control characters and
 is probably safe to read on an ASCII terminal), executable (the file con‐
 tains the result of compiling a program in a form understandable to some
 UNIX kernel or another), or data meaning anything else (data is usually
 “binary” or non-printable).  Exceptions are well-known file formats (core
 files, tar archives) that are known to contain binary data.  When adding
 local definitions to /etc/magic, make sure to preserve these keywords.
 Users depend on knowing that all the readable files in a directory have
 the word “text” printed.  Don't do as Berkeley did and change “shell
 commands text” to “shell script”.

Bạn cũng có thể sử dụng một mẹo để chạy trực tiếp tên này của tên thực thi trong $PATH:

$ file $(type -p add-apt-repository | awk '{print $NF}')
/usr/local/bin/add-apt-repository: Python script, ASCII text executable
$ file $(type -p ab | awk '{print $NF}')
/usr/bin/ab: ELF 64-bit LSB  shared object, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=569314a9c4458e72e4ac66cb043e9a1fdf0b55b7, stripped

Để tìm loại tệp của tất cả các tệp thực thi có thể tìm thấy trong các thư mục của bạn $PATH, bạn có thể làm điều này:

find $(printf "$PATH" | sed 's/:/ /g') -type f | xargs file

Và để chạy filetrên tất cả các tệp trong một thư mục cụ thể ( /usr/binví dụ), chỉ cần làm

file /usr/bin/*

Nhưng chúng ta phải chạy filecho mỗi tệp để xem loại tệp này là gì. Có phương pháp đơn giản nào cho tất cả các tệp không?
Avinash Raj

3
@AvinashRaj cho tất cả các tệp trong một thư mục nhất định? Cứ làm đi file /usr/bin/*. Cũng giống như bất kỳ lệnh nào khác.
terdon

5

Trên thực tế, sự khác biệt giữa những điều đó không phải là tuyệt vời.

Trên một hệ thống Unix hoặc Linux điển hình, có ít hơn năm tệp thực thi thực sự. Trên Ubuntu, đây là /lib/ld-linux.so.2/sbin/ldconfig.

Mọi thứ khác được đánh dấu thực thi được chạy qua một trình thông dịch , trong đó hai định dạng được hỗ trợ:

  1. Các tệp bắt đầu bằng #!sẽ có tên trình thông dịch giữa ký tự này và ký tự dòng mới đầu tiên (điều đó đúng, không có yêu cầu "tập lệnh" nào là tệp văn bản).
  2. Các tệp ELF có một PT_INTERPphân đoạn cung cấp đường dẫn đến trình thông dịch (thường /lib/ld-linux.so.2).

Khi một tệp như vậy được thực thi, kernel sẽ tìm tên của trình thông dịch và gọi nó thay thế. Điều này có thể xảy ra đệ quy, ví dụ khi bạn chạy tập lệnh shell:

  1. Nhân mở kịch bản, tìm thấy #! /bin/shở đầu.
  2. Nhân mở ra /bin/sh, tìm PT_INTERPđoạn chỉ vào /lib/ld-linux.so.2.
  3. Nhân mở ra /lib/ld-linux.so.2, thấy rằng nó không có PT_INTERPphân đoạn, tải phân đoạn văn bản của nó và khởi động nó, chuyển tay cầm mở tới /bin/shvà dòng lệnh cho lệnh gọi tập lệnh của bạn.
  4. ld-linux.so.2tải các đoạn mã từ /bin/sh, giải quyết các tham chiếu thư viện dùng chung và bắt đầu chức năng chính của nó
  5. /bin/sh sau đó mở lại tệp script và bắt đầu diễn giải từng dòng một.

Từ quan điểm của kernel, sự khác biệt duy nhất là đối với tệp ELF, bộ mô tả tệp mở được truyền chứ không phải tên của tệp; điều này chủ yếu là tối ưu hóa Việc trình thông dịch sau đó quyết định chuyển đến một đoạn mã được tải từ tệp hay giải thích nó theo từng dòng chỉ do người phiên dịch quyết định và chủ yếu dựa trên quy ước.


Thông tin tốt, nhưng không thực sự là một câu trả lời cho câu hỏi này.
OrangeDog

Câu trả lời là Mu .
Simon Richter

1

Lệnh tệp là tuyệt vời, nhưng đối với công cụ phân tích chuyên nghiệp hơn, tôi muốn bạn thử gói TrID là công cụ Định danh tệp.

TrID là một tiện ích được thiết kế để xác định các loại tệp từ chữ ký nhị phân của chúng và rất dễ sử dụng.

Để biết thêm thông tin và gói chỉ cần truy cập: Trang web

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.