- How to make a file executable in linux?
- Own your bits
- The real power of Linux executables
- What involves executing a file
- The kernel side of things
- ELF binaries
- What about scripts?
- Execute anything with bitfmt_misc
- References
- How To Compile And Run a C/C++ Code In Linux
- Step #1: Install C/C++ compiler and related tools
- Step #2: Verify installation
- How to Compile and Run C/C++ program on Linux
- How do I compile the program on Linux?
- How do I run or execute the program called demo on Linux?
- Compiling and running a simple C++ program
- How do I generate symbolic information for gdb and warning messages?
- How do I generate optimized code on a Linux machine?
- How do I compile a C program that uses math functions?
- How do I compile a C++ program that uses Xlib graphics functions?
- How do I compile a program with multiple source files?
How to make a file executable in linux?
Aug 30, 2016 · 2 min read
Asked by Satyam
To give a little more context, I think that this question stems from the distinction between executable and non executable files on windows, characterized by the .exe extension.
In linux, every file can be an executable.
Let’s see what happens when you try to execute a file. First, we need to have a file. We can use the echo command and redirect its output to create a new file.
Note the lack of extension i n the filename. We could have named it hello.txt, or hello.sh, it’s entirely upto us, the extension mostly doesn’t matter. Unlike windows, you don’t need a special extension to make a file executable.
Now, we’ll execute the file.
Let’s go over what happened.
To execute a file all we need to do is enter the path of the file on the command prompt. We’ll also need execute permissions on the file, like to read a file we’d need read permissions. Note that setting or removing the execute permissions does not make a file executable or non-executable, but it just takes away or gives us the ability to execute it.
What exactly happens when we ‘execute’ a file is that the contents of the file are sent to the program located on the first line. In this case, it’s /bin/bash.
This means that all contents of the file are being sent to bash. So it’s as if you were typing those commands into the shell. Therefore, in the file we’ve created it ran the echo command.
Please note that there’s nothing special with ./, it just simply means ‘look for the file in the current directory’. It could have been any path, for example
And you could also have some other program handle the execution. For example, consider the following file in which I’ve set the first line to be the location of python binary, which I found via the command whereis python. It may be different on your system.
You could also set a .doc file’s permissions as executable, or a .jpg file. It’s perfectly legal. But when you try to execute those, their contents will be sent to shell to be parsed as shell commands. But they aren’t shell commands, so you’ll get an error.
Источник
Own your bits
Technology with a focus on Open Source
The real power of Linux executables
What happens when a file gets executed in Linux? What does it mean that a file is executable? Can we only execute compiled binaries? What about shell scripts then? If I can execute shell scripts, what else can I execute? In this article we will try to answer those questions.
What involves executing a file
Starting from the basics, let’s try to understand what happens when we type the following in our terminal
The way our programs in the userspace interact with the kernel is through system calls. In practice we need to interact with the kernel to do almost anything that is interesting, such as printing output, reading input, reading files and so on.
The syscall that is in charge of executing files is the execve() system call. When we are coding, we normally access it through the exec family of functions present in the standard library, or even more commonly through higher level abstractions such as popen() or system().
It is important to note that when we execute a file through execve() , no new process is generated. Instead, our calling process will mutate into an instance of execution of the new executable. The PID won’t change, but the machine code, data, heap and stack of the process will be replaced inside the kernel space.
This is different to the way we are used to launching executables from the terminal. When we type sleep 30 in the terminal, we get a child process of bash, and the latter does not disappear.
Here another system call is coming into play, the fork() syscall. bash will first create a copy of itself in another child process, and then this child process will call execve() in order to transform itself into sleep. This way bash doesn’t disappear, and will be there to take over control when sleep dies after 30 seconds.
We can skip the forking step through the exec bash bultin
In another terminal we can see that sleep takes over the PID
And sure enough, after 30 seconds when sleep exits there is no bash session, so the terminal window will close.
The kernel side of things
So far we have seen the userspace interacting through syscalls, let’s look at what happens at the other side.
The implementation of those syscalls lives in the kernel. In general lines, the execve() syscall requests the kernel the execution of a certain file in disk, and the kernel needs to load that file into memory where it can be accessed by the CPU.
This is the entry point of the system call, at fs/exec.c
From here, the kernel first performs all required preparations in order to start executing a binary, such as setting up the virtual memory for the process
, and setting the filename, command line arguments, and inherited environment. Yes, environment variables are also first class citizens of the Linux kernel.
Finally, the file “will be executed”.
ELF binaries
Binaries are not only a big blob of machine code. Modern binaries are using the binary ELF format, for Executable and Linkable Format. In simple terms, this is a way of packaging the different code and data sections with some attributes, such as write protection for the .text code section, so that they get mapped into virtual memory for execution. In addition, there are machine independent headers that provide basic information about the executable, such as wether is statically or dynamically linked, the architecture and so on.
The kernel code responsible for parsing the ELF format lives in fs/binfmt_elf.c. Here, the ELF headers are read and analyzed
, and the PT_LOAD sections are loaded into virtual memory
This is just slightly more convoluted for dynamically linked programs. The kernel recognizes a dynamically linked program by the presence of the PT_INTERP header.
This header is hardcoded at compile time with the path of the runtime linker ld-linux-x86-64.so that needs to be used to run it. The runtime linker will find in the filesystem the .so libraries that the binary needs to execute, and will load them into memory.
In this simple case only the standard C library needs to be dynamically linked, because vDSO is a special virtual library put there for efficient execution of read only syscalls.
The kernel will recognize the PT_INTERP header, and will also load the runtime linker (a.k.a ELF interpreter) ld.so and execute it.
Then ld.so will find and load the .so dynamic libraries, or fail if any undefined symbol remains unresolved, and finally will jump execution to the beginning (AT_ENTRY) of the original binary code.
We get the idea that the kernel is the one that inspects the binary and handles it, but in reallity, we are not executing our binary, but the ELF interpreter ld.so instead. Technically it is our binary’s machine code that it is still being executed but we are faced with a concept, the interpreter which is the one that is actually executable, and that is the one actually “interpreting” our file.
At the end of the day, we are doing this
What about scripts?
I have been trying hard to avoid the word binary because you can actually “execute” files that are not binary. These files are technically not executed themselves, because they don’t necessarily contain machine code, but by an interpreter as we just saw.
Now, let’s look at how a executable script is run. I used to imagine that the bash process (or the file manager) inspects the first bytes of the file, and if it finds the shebang, for instance #!/bin/python2 , then it calls the appropriate interpreter. Turns out this is not how it works. The shebang detection actually happens in the Linux Kernel itself.
This means there is more to execution than just ELF: Linux supports a bunch of binary formats, being ELF just one of them. Inside the kernel, each binary format is run by a handler that knows how to deal with said file. There are some handlers that come with the standard kernel, but some others can be added through loadable modules.
Whenever a file is to be executed through execve(), its 128 first bytes are read and passed on to every handler. This occurs at fs/exec.c
Each handler can then accept it or ignore it, usually depending on some magic in the first bytes of the binary. This way, the appropriate handler takes care of the execution of that binary, or passes on the chance of doing so to another handler.
In the case of the ELF format, the magic is 0x7F ‘ELF’ in the field e_ident
This is checked by the ELF handler at binfmt_elf.c in order to accept the binary.
So what happens with scripts? well, it turns out that there is a handler for that in the kernel, that can be found at binfmt_script.c.
All binary format handlers offer an interface to the execve(), for instance this is the one for the ELF format
The main hook here is the load_binary() function that will be different for each handler.
In the case of the script handler, its load_binary() hook is at binfmt_script.c, and starts like this.
So it is the kernel who actually parses the first line of the script, and passes on execution to the interpreter with the script path as an argument. As long as the file starts with the shebang #!, it will be interpreted as a script, be it python, awk, sed, perl, bash, ash, sh, zsh or any similar other.
Once more, we are not actually executing our script, but we are doing something like
We are starting to see that the name binary format is a bit misleading, as we can execute things that are not binaries. There are other handlers for exotic or old binary formats, such as the flat format, or the old a.out format, and in particular there is a very powerful and versatile handler, the binfmt_misc handler.
Execute anything with bitfmt_misc
Now we know what a binary handler is, and we can understand binfmt_misc. This is a flexible format handler that allows us to specify what userland interpreter should run for a specific file type. It doesn’t just look at a hardcoded magic at the beginning of the file, but also supports detecting the binary by extension, using masks, and offers a /proc interface to the system administrator. Remember that all this is happening in kernel space. The loader for this handler is load_misc_binary() at fs/binfmt_misc.c.
If the /proc interface is not already mounted for us, we can do so with
Let’s have a look at it
We can see that we already have it populated with some python and other entries.
We can remove, enable or disable these entries.
- echo 1 to enable entry
- echo 0 to disable entry
- echo -1 to remove entry
What is really cool is that we can easily add custom entries through binfmt_misc. In order to add an entry, you echo a format string to register. Details on how to configure all these flags, masks and magic values can be found here.
As an example, let’s create a handler for the JPG image format to be opened by the feh image viewer. In this case we are matching by extension (therefore the E )
The handler is registered now. We can inspect it
Now let’s take a picture, make executable, et voila.
Let’s now create an executable TODO list, based on magic number detection ( M ).
PDFs start with the text %PDF , as seen in the specification.
Another example, Libreoffice files by extension
We have all the new entries in proc
With this technique we can run transparently Java applications (based on the 0xCAFEBABE magic)
This requires the use of a wrapper, that you can get from the Arch Wiki.
This also works for Mono, and even DOS! In order to run good old Civilization transparently, install dosbox, configure binfmt_misc
Some goes for Windows emulated binaries
The problem is that all DOS, Windows and Mono binaries share the same MZ magic, so in order to combine them, we would need to use a special wrapper that is able to detect the differences deeper in the file, such as start.exe.
If we want to make these settings permanent, we can setup this configuration at boot time at /etc/binfmt.d. For instance, if we wanted to setup the PDF handler at boot time, we just add a new file to the folder
We can see that this approach is very flexible and powerful. One problem with it is that it is a bit unconventional to have “regular files” other than scripts as executable. The good thing about it is that it is truly a system wide setting, so once you set it up in the kernel, it will work from all your shells, file managers and any other user of the execve() system call.
We will see some more useful things we can do with binfmt_misc in the following post.
References
This article aims at being a gentle overview of binfmt_misc and the execution process with some practical examples. If you want the gory details, consider reading the following references.
Источник
How To Compile And Run a C/C++ Code In Linux
I am a new Linux user and student who used to write C or C++ programs on MS-Windows. Now, I am using Ubuntu Linux. How can I compile a C or C++ program on Linux operating systems using bash Terminal application?
To compile a C or C++ program on any Linux distro such as Ubuntu, Red Hat, Fedora, Debian and other Linux distro you need to install:
Tutorial details | |
---|---|
Difficulty level | Easy |
Root privileges | No |
Requirements | GNU C/C++ compiler |
Est. reading time | 2 minutes |
- GNU C and C++ compiler collection
- Development tools
- Development libraries
- IDE or text editor to write programs
Step #1: Install C/C++ compiler and related tools
If you are using Fedora, Red Hat, CentOS, or Scientific Linux, use the following yum command to install GNU c/c++ compiler:
# yum groupinstall ‘Development Tools’
If you are using Debian or Ubuntu Linux, type the following apt-get command to install GNU c/c++ compiler:
$ sudo apt-get update
$ sudo apt-get install build-essential manpages-dev
Step #2: Verify installation
Type the following command to display the version number and location of the compiler on Linux:
$ whereis gcc
$ which gcc
$ gcc —version
Sample outputs:
Fig. 01: GNU C/C++ compilers on Linux
How to Compile and Run C/C++ program on Linux
Create a file called demo.c using a text editor such as vi, emacs or joe:
How do I compile the program on Linux?
Use any one of the following syntax to compile the program called demo.c:
In this example, compile demo.c, enter:
If there is no error in your code or C program then the compiler will successfully create an executable file called demo in the current directory, otherwise you need fix the code. To verify this, type:
$ ls -l demo*
How do I run or execute the program called demo on Linux?
Simply type the the program name:
$ ./demo
OR
$ /path/to/demo
Samples session:
Animated gif 01: Compile and run C and C++ program demo
Compiling and running a simple C++ program
Create a program called demo2.C as follows:
To compile this program, enter:
To run this program, type:
- No ads and tracking
- In-depth guides for developers and sysadmins at Opensourceflare✨
- Join my Patreon to support independent content creators and start reading latest guides:
- How to set up Redis sentinel cluster on Ubuntu or Debian Linux
- How To Set Up SSH Keys With YubiKey as two-factor authentication (U2F/FIDO2)
- How to set up Mariadb Galera cluster on Ubuntu or Debian Linux
- A podman tutorial for beginners – part I (run Linux containers without Docker and in daemonless mode)
- How to protect Linux against rogue USB devices using USBGuard
Join Patreon ➔
How do I generate symbolic information for gdb and warning messages?
The syntax is as follows C compiler:
cc -g -Wall input.c -o executable
The syntax is as follows C++ compiler:
g++ -g -Wall input.C -o executable
How do I generate optimized code on a Linux machine?
The syntax is as follows C compiler:
cc -O input.c -o executable
The syntax is as follows C++ compiler:
g++ -O -Wall input.C -o executable
How do I compile a C program that uses math functions?
The syntax is as follows when need pass the -lm option with gcc to link with the math libraries:
cc myth1.c -o executable -lm
How do I compile a C++ program that uses Xlib graphics functions?
The syntax is as follows when need pass the -lX11 option with gcc to link with the Xlib libraries:
g++ fireworks.C -o executable -lX11
How do I compile a program with multiple source files?
The syntax is as follows if the source code is in several files (such as light.c, sky.c, fireworks.c):
cc light.c sky.c fireworks.c -o executable
C++ syntax is as follows if the source code is in several files:
g++ ac.C bc.C file3.C -o my-program-name
See gcc(1) Linux and Unix man page for more information.
🐧 Get the latest tutorials on Linux, Open Source & DevOps via
Category | List of Unix and Linux commands |
---|---|
Documentation | help • mandb • man • pinfo |
Disk space analyzers | df • duf • ncdu • pydf |
File Management | cat • cp • less • mkdir • more • tree |
Firewall | Alpine Awall • CentOS 8 • OpenSUSE • RHEL 8 • Ubuntu 16.04 • Ubuntu 18.04 • Ubuntu 20.04 |
Linux Desktop Apps | Skype • Spotify • VLC 3 |
Modern utilities | bat • exa |
Network Utilities | NetHogs • dig • host • ip • nmap |
OpenVPN | CentOS 7 • CentOS 8 • Debian 10 • Debian 8/9 • Ubuntu 18.04 • Ubuntu 20.04 |
Package Manager | apk • apt |
Processes Management | bg • chroot • cron • disown • fg • glances • gtop • jobs • killall • kill • pidof • pstree • pwdx • time • vtop |
Searching | ag • grep • whereis • which |
Shell builtins | compgen • echo • printf |
Text processing | cut • rev |
User Information | groups • id • lastcomm • last • lid/libuser-lid • logname • members • users • whoami • who • w |
WireGuard VPN | Alpine • CentOS 8 • Debian 10 • Firewall • Ubuntu 20.04 |
Comments on this entry are closed.
thank you so much ur solution gave a relief…
it made my gcc command to work
Very nice article…..
In Fig. 01, you did “whereis” twice. Shouldn’t it be “which” the second time? Thanks for the tut though. Big fan!
Another mistake, please change the following comment:
## assuming that executable-file-name.c exists ##
to
## assuming that program-source-code.c exists in the current directory ##
how to compile a program that use math functions and other things?
For the sake of supplying an example, let’s say you want to use the cosine function. This is supplied in the Linux math library. The cosine function is called ‘cos()’. Similarly, the sine function is called ‘sin()’.
First, to find information about how to use them, type “man cos” in a terminal session. This gives you the manual page for the cosine function. The output from ‘man’ may vary for your system, but it likely tells you three things: 1. first, include the math.h header, 2. cos() takes a ‘double’ as its argument and it returns a double as its output, 3. to build your program, tell the C compiler to include the math library (-lm).
Here’s a sample program that does all of this:
Love it!
Thank you. I have a trouble in doing step 1 and 2. But they are fixed.
thank u ,
need pdf of the commands guide to access the c/c++/java.
to compile and run a c++ program in ubuntu follow these simple steps:
1 open terminal window.
2 type “gedit” .
3 A gedit window will appear whereyou can write your program.
4 save your program as “filename.cpp” on desktop, “.cpp” is compulsory.
5 open terminal again and type “cd Desktop”.
6 In second line type “g++ filename.cpp”.
7 Type “./a.out”.
NOW YOUR WILL RUN.
very nice to your step.
thanks
Thanks! This article really helped me to find the GNU compiler in a Linux Operating System and showed me how to compile a C program.
dear sir,
what is the procedure to run .cpp program in linux distro debian 5 ?
just about to get around to learning c along with teaching my sons it. i had no idea where to start, the first page i checked is a bumper bonanza.
Источник