Як знайти різницю між файлом сценарію та бінарним файлом?


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 ---------

У вищесказаному adbє двійковий файл і add-apt-repositoryце файл сценарію. Я отримую цю інформацію, переглядаючи файли через nautilus. Але через командний рядок я не знайшов різниць. Я не в змозі передбачити, чи є файл бінарним файлом або файл сценарію.

Тож як я можу розрізняти скрипт і бінарні файли за допомогою командного рядка?

Відповіді:


16

Просто використовуйте 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

Як пояснено в 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”.

Ви також можете скористатися трюком, щоб запустити це безпосередньо на ім'я виконавчого файлу у вашому $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

Щоб знайти тип файлу всіх виконуваних файлів, які можна знайти у ваших каталогах $PATH, ви можете зробити це:

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

А для запуску fileвсіх файлів у певному каталозі ( /usr/binнаприклад,) просто зробіть

file /usr/bin/*

Але ми повинні запустити fileкожен файл, щоб побачити, який тип файлу це. Чи є простий метод для всіх файлів?
Avinash Raj

3
@AvinashRaj для всіх файлів у заданому каталозі? Просто роби file /usr/bin/*. Як і будь-яка інша команда.
тердон

5

Власне, відмінності між ними не такі великі.

У типовій системі Unix або Linux існує менше п'яти реальних виконуваних файлів. На Ubuntu це /lib/ld-linux.so.2і є /sbin/ldconfig.

Все інше, що позначено виконуваним, запускається через інтерпретатор , для якого підтримуються два формати:

  1. Файли, що починаються з #!, матимуть ім'я інтерпретатора між цим та першим символом нового рядка (саме так, немає вимоги, щоб "сценарії" були текстовими файлами).
  2. Файли ELF мають PT_INTERPсегмент, який дає шлях до перекладача (як правило /lib/ld-linux.so.2).

Коли такий файл виконується, ядро ​​знаходить ім'я інтерпретатора і викликає його замість нього. Це може статися рекурсивно, наприклад, коли ви запускаєте скрипт оболонки:

  1. Ядро відкриває скрипт, знаходить #! /bin/shна початку.
  2. Ядро відкривається /bin/sh, знаходить PT_INTERPсегмент, на який вказує /lib/ld-linux.so.2.
  3. Ядро відкривається /lib/ld-linux.so.2, виявляє, що у нього немає PT_INTERPсегмента, завантажує його текстовий сегмент і запускає його, передаючи відкриту ручку /bin/shта командний рядок для виклику сценарію.
  4. ld-linux.so.2завантажує сегменти коду з /bin/sh, вирішує спільні бібліотечні посилання та запускає його основну функцію
  5. /bin/sh потім знову відкриває файл сценарію і починає інтерпретувати його по черзі.

З точки зору ядра, різниця полягає лише в тому, що для файлу ELF відкритий дескриптор файлу передається, а не ім'я файлу; це здебільшого оптимізація. Чи вирішить перекладач перейти до кодового сегмента, завантаженого з файлу, чи інтерпретувати його по рядку, вирішує лише інтерпретатор, і здебільшого ґрунтується на конвенції.


Хороша інформація, але насправді не відповідь на це питання.
OrangeDog

Відповідь - Му .
Саймон Ріхтер

1

Команда файлів чудова, але для більш професійного аналізу інструменту я хотів би, щоб ви спробували пакет TrID, який є інструментом ідентифікатора файлів.

TrID - це утиліта, призначена для виявлення типів файлів з їх двійкових підписів та їх простоти у використанні.

Для отримання додаткової інформації та пакету просто відвідайте: Сайт

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.