- How to find binary files in a directory?
- 10 Answers 10
- Edit
- Original answer
- Edit 2
- How to find all binary executables recursively within a directory?
- 4 Answers 4
- Use “which” in Linux to find the Location of an Exetable
- Ubuntu/Debian Series Overview
- Locate an Executable in Linux With which
- How to use the which command
- Using Options
- Get Notified on New Future Studio Content and Platform Updates
How to find binary files in a directory?
I need to find the binary files in a directory. I want to do this with file, and after that I will check the results with grep. But my problem is that I have no idea what is a binary file. What will give the file command for binary files or what should I check with grep?
What kind of «binary» files are you talking about here? Do you have an appropriate «binary» file on your system anywhere? What does file say about it?
I don’t know what kind of binary files, because my homework doesn’t define it, only: write a shell script using grep command (and others) to find the binary files in a directory and write their permissions. So i don;t know nothing about binary files type.
That seems under-specific to me. I’d ask for clarification. Though given the suggestion to use grep I’m going to guess it means «contains a NUL byte».
All files are binary. «Binary» means you don’t know the actual format of the file or it is not important in the context. Some files are text files. A text file is one where the entire file can be decoded into a text string with a specific character encoding. All files can be decoded using several different character encodings. It is only valid to do so if you know the file is text and use the character encoding that was used to write it.
10 Answers 10
This finds all non-text based, binary, and empty files.
Edit
Solution with only grep (from Mehrdad’s comment):
Original answer
This does not require any other tool except find and grep :
find . -type f -exec grep -IL . "<>" \;
-I tells grep to assume binary files as unmatched
-L prints only unmatched files
Edit 2
This finds all non-empty binary files:
find . -type f ! -size 0 -exec grep -IL . "<>" \;
It looks like you’re right. However it’s quite some time ago that I looked into this so I don’t remember why I put the find there. Without the additional fork this it’s also way faster!
Maybe the files you think are ‘non-binary’ are empty? Those show up, too (as they are not text, I guess)
Just have to mention Perl‘s -T test for text files, and its opposite -B for binary files.
$ find . -type f | perl -lne 'print if -B'
will print out any binary files it sees. Use -T if you want the opposite: text files.
It’s not totally foolproof as it only looks in the first 1,000 characters or so, but it’s better than some of the ad-hoc methods suggested here. See man perlfunc for the whole rundown. Here is a summary:
The «-T» and «-B» switches work as follows. The first block or so of the file is examined to see if it is valid UTF-8 that includes non-ASCII characters. If, so it’s a «-T» file. Otherwise, that same portion of the file is examined for odd characters such as strange control codes or characters with the high bit set. If more than a third of the characters are strange, it’s a «-B» file; otherwise it’s a «-T» file. Also, any file containing a zero byte in the examined portion is considered a binary file.
In these modern times (2020 is practically the 3rd decade of the 21st century after all), I think the correct question is how do I find all the non-utf-8 files? Utf-8 being the modern equivalent of a text file.
utf-8 encoding of text with non-ascii code points will introduce non-ascii bytes (i.e., bytes with the most significant bit set). Now, not all sequences of such bytes form valid utf-8 sequences.
isutf8 from the moreutils package is what you need.
$ isutf8 -l /bin/* /bin/[ /bin/acyclic /bin/addr2line /bin/animate /bin/applydeltarpm /bin/apropos ⋮
$ file $(isutf8 -l /bin/*) /bin/[: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=4d70c2142fc672d8a69d033ecb6693ec15b1e6fb, for GNU/Linux 3.2.0, stripped /bin/acyclic: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=d428ea52eb0e8aaf7faf30914710d8fbabe6ca28, for GNU/Linux 3.2.0, stripped /bin/addr2line: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=797f42bc4f8fb754a49b816b82d6b40804626567, for GNU/Linux 3.2.0, stripped /bin/animate: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=36ab46e69c1bfea433382ffc9bbd9708365dac2b, for GNU/Linux 3.2.0, stripped /bin/applydeltarpm: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=a1fddcbeec9266e698782596f2dfd1b4f3e0b974, for GNU/Linux 3.2.0, stripped /bin/apropos: symbolic link to whatis ⋮
You may wish to invert the test and get all the text files. Use -i :
$ isutf8 -il /bin/* /bin/alias /bin/bashbug /bin/bashbug-64 /bin/bg ⋮ $ file -L $(isutf8 -il /bin/*) /bin/alias: a /usr/bin/sh script, ASCII text executable /bin/bashbug: a /usr/bin/sh - script, ASCII text executable, with very long lines /bin/bashbug-64: a /usr/bin/sh - script, ASCII text executable, with very long lines /bin/bg: a /usr/bin/sh script, ASCII text executable ⋮
Yeah, it reads the whole file, but it’s pretty speedy, and if you want accuracy…
How to find all binary executables recursively within a directory?
all executable files are listed (excluding directories), and including executable script file (like script.sh, etc). What I want to do is list only binary executable files.
4 Answers 4
You might try the file utility. According to the manpage:
The magic tests are used to check for files with data in particular fixed formats. The canonical example of this is a binary executable (compiled program) a.out file, whose format is defined in , and possibly in the standard include directory.
You might have to play around with the regular expression but something like:
$ find -type f -executable -exec file -i '<>' \; | grep 'x-executable; charset=binary'
file has lots of options, so you might want to take a closer look at the man page. I used the first option I found that seemed to output easily-to-grep output.
I’d say use find -type f -executable -exec sh -c «file -i ‘<>‘ | grep -q ‘x-executable; charset=binary'» \; -print . It will only give you files (and thus can be passed to the next command he wants to run)
serverfault.com/a/584595/211551 solution finds files that are NOT marked executable but are executable.
On OS X, you can install GNU find with brew install findutils or sudo port install findutils and then you can run an invocation like this to a similar effect: gfind . -type f -executable -exec file ‘<>‘ \; | grep -i execut
Here’s a way to exclude scripts, i.e., files whose first two characters are #! :
find -type f -executable -exec sh -c 'test "$(head -c 2 "$1")" != "#!"' sh <> \; -print
For some kinds of files, it’s not clear whether you want them classified as scripts or binary, for example bytecode files. Depending on how things are set up, these may or may not start with #! . If these matter to you, you’ll have to make the inner shell script more complex. For example, here’s how you might include ELF binaries and Mono executables and Objective Caml bytecode programs but not other kinds of executables like shell scripts or perl scripts or JVM bytecode programs:
find -type f -executable -exec sh -c ' case "$(head -n 1 "$1")" in ?ELF*) exit 0;; MZ*) exit 0;; #!*/ocamlrun*) exit 0;; esac exit 1 ' sh <> \; -print
Use “which” in Linux to find the Location of an Exetable
Linux comes with the which command to locate a given executable. Executables are commands you type into your terminal, like git , node , touch , or vim .
Sometimes, you want to find the location of an executable on your filesystem. That’s where the which command comes handy. Read on to find out how to use which !
Ubuntu/Debian Series Overview
- Fix “sudo command not found”
- Install a Specific Version with apt-get on Ubuntu/Debian
- Fix Ubuntu/Debian apt-get “KEYEXPIRED: The following signatures were invalid”
- How to Test a Cron Job
- How to Unzip Into a Folder
- How to Show Your Elasticsearch Version on Ubuntu/Debian
- Use “which” in Linux to find the Location of an Exetable
- Sort “ls” by Last Changed Date
- How to Shutdown a Machine
Locate an Executable in Linux With which
Using which parses the PATH environment variable to find all locations to search for a program.
How to use the which command
The which command has the following syntax:
For example, you may locate the git program like this:
You can also locate more than one program in a single call by adding all programs separated by a space:
$ which git node vim /usr/bin/git /usr/local/bin/node /usr/bin/vim
Using Options
The which command supports two options:
-a List all instances of executables found (instead of just the first one of each). -s No output, just return 0 if all of the executables are found, or 1 if some were not found.
If a command is present in multiple locations, you can find all occurrences using the -a option.
Using -s changes the output of which when programs are not found. Let’s say you don’t have MongoDB installed. Trying to locate the mongod executable results in different outputs depending on whether you append the -s option:
$ which mongod # no output at all # and with the “-s” option $ which mongod mongod not found
The -s option allows you to retrieve expressive results. This is helpful when you as a human runs the command. In shell scripts, you may want to check for empty outputs to determine whether an executable is missing.
Get Notified on New Future Studio
Content and Platform Updates
Get your weekly push notification about new and trending
Future Studio content and recent platform enhancements