Binary files contain encoded executable code to be run on an operating system. Unlike plaintext, binaries cannot be easily read or edited by humans. As a Linux developer, understanding how to execute binaries is essential. This comprehensive guide will cover binary formats, setting execute permissions, troubleshooting errors, best practices, and more using developer-focused examples.

Binary File Formats in Linux

There are various binary executable formats supported on Linux systems:

ELF Binaries

The Executable and Linkable Format (ELF) is the standard for binaries on Linux, as well as other Unix-based systems. This includes compiled applications written in languages like C/C++, Rust etc. as well as system components like the Linux kernel itself.

Here is the structure of a 64-bit ELF binary:

+------------------------+
|       ELF Header       |
+------------------------+
|  Program Header Table  | Stores metadata to load binary 
+------------------------+
|         Code           | Instructions & data 
+------------------------+ 
|         Data           | Global & static variables
+------------------------+
|      Section Table     | Extra data/debug info 
+------------------------+

When executed, the operating system loads different segments into memory as per the program header table.

Script Binaries

Scripts for languages like Bash, Python, Perl have the interpreter path defined within them. When executed, this interpreter reads and executes the script line-by-line or compiles it to bytecode.

Java Bytecode

Java class files contain platform-independent bytecode that is Just-In-Time (JIT) compiled to optimized native machine code.

.NET PE and DLL Files

Windows .NET applications and dynamic libraries utilize the Portable Executable (PE) format with headers like MS-DOS stub. They run on Linux using .NET Core runtime.

So in summary – executable binaries have headers describing how the OS loader should map them into memory, along with the compiled machine code. Scripts embed their interpreter path to process them at runtime.

Setting Execute Permissions in Linux

For security reasons, Linux restricts permissions on all files and directories including binaries. Running them requires explicitly enabling execute flags:

Permission Flag Binary Meaning
– rwx rwx rwx Executable by all users
– rw- — — Only the owner has read/write permission
– rwx — r– Owner can execute, others have read permission

The full code to make a binary executable:

chmod u+x binary_name # Enable execute for the owner 
chmod +x binary_name # Enable execute for all users

Additionally:

  • The setuid and setgid permission bits allow executing a binary with permissions of the owner/group respectively.

  • The sticky bit prevents users from deleting or renaming files in that folder.

Mastering setting Linux file permissions is key for developers working with binaries.

Running the Executable Binary

With the execute flag enabled, you can run the binary by invoking its absolute or relative path in the terminal:

/usr/bin/ffmpeg -i input.mp4 output.avi # Absolute path  

./my_application --arg value # Relative path   

If you get a "Permission denied" error, prefix sudo to run the binary as root or superuser.

When running a binary:

  • The system architecture should match (x86, ARM etc.)
  • Dependent shared libraries must be available
  • Any runtime parameters or flags should be provided

Now let‘s go through some examples of common Linux binaries developers work with.

Bash Script Binaries

Bash scripts have the path to the /bin/bash interpreter. The shebang line starting with #! indicates this:

#!/bin/bash
echo "Hello World!"

To execute after adding execute permission:

$ ./script.sh
Hello World!

The same method applies for Perl, Python, Ruby and other scripting language binaries.

Installers and Packages

Software distributed as binary installers or Linux packages need to be set executable before running:

$ chmod +x install_app.bin
$ sudo ./install_app.bin
. . . 
Installation Complete!

Vendor-provided installers typically have arguments or accept End-User License Agreements before installing.

System Binaries

Existing system binaries like compilers and debug tools already have permissions configured:

$ g++ -o myapp myapp.cpp    # Invoke C++ compiler
$ valgrind ./myapp          # Check for memory leaks

So with sudo privileges, developers can directly leverage them.

Troubleshooting Binary Execution

Some common errors seen when running binaries and their fixes:

Error Message Resolution
Permission denied Enable execute permissions using chmod +x or run with sudo
No such file or directory Check binary path, libraries missing
Exec format error Mismatch between binary and system architecture

Checking dependency libraries, architecture matching, and setting file permissions properly help avoid these.

Best Practices

Some best practices for securely running binaries:

  • Review checksums or signatures before executing downloaded binaries
  • Scan files with AV heuristics before allowing execution
  • Run untrusted binaries inside sandboxes or containers
  • Limit binary capabilities via Security-Enhanced Linux (SELinux)

Following these processes improves security on multi-user Linux systems.

Conclusion

This exhaustive guide covered binary executable formats in Linux, setting execute permissions correctly, running various binary types from the terminal, troubleshooting errors like missing libraries, best practices like sandboxing, and more.

Mastering binary execution from a Linux developer perspective allows efficiently building, distributing, and running applications across different distributions and architectures. It unlocks taking advantage of the powerful Linux toolchain.

Similar Posts