Learn through the super-clean Baeldung Pro experience:
>> Membership and Baeldung Pro.
No ads, dark-mode and 6 months free of IntelliJ Idea Ultimate to start with.
Last updated: October 18, 2024
Executing a Linux command from a C program allows developers to perform system-level operations such as file manipulation, process control, and interaction with the operating system. This feature is useful for system programming, automation, and integrating shell commands into C-based programs.
In this tutorial, we’ll explore various ways to run Linux commands from a C program.
The system() method provides an easy way to run a Linux command from a C program. It allows us to pass a string containing a shell command, which the operating system will execute.
The command executes as if we had put it directly into the terminal, and the program waits for the command to finish before proceeding:
#include <stdio.h>
#include <stdlib.h>
int main() {
system("ls -l");
return 0;
}
In this example, we use the system() method to execute the ls -l Linux command, which lists all files in the current directory. Once this command is completed, the program continues execution.
Thus, system() is a straightforward and useful method for executing Linux commands from a C program. It’s perfect for circumstances in which we don’t need to record output or interact with the command while it’s running.
The popen() method allows a C program to interact with the command’s input or output via a pipe, making it more flexible for running Linux commands. Furthermore, popen() establishes a connection between the C application and the command. This implies that we can either capture the command’s output or supply input to it, depending on the mode we choose when opening the pipe:
#include <stdio.h>
#include <stdlib.h>
int main() {
char buffer[128];
FILE *fp = popen("ls -l", "r");
if (fp == NULL) {
perror("popen failed");
return 1;
}
while (fgets(buffer, sizeof(buffer), fp) != NULL) {
printf("%s", buffer);
}
pclose(fp);
return 0;
}
In this example, the program executes the ls -l command in r mode and collects the output through a pipe. The popen() method returns a file pointer fp that points to the command’s output. The fgets() method reads the command output line by line, stores it in the buffer, and then prints each line to the screen. Once the command is complete, we can free up system resources by using pclose() to close the pipe.
Additionally, setting the mode to r implies that we want to receive the command’s output. We can also set the mode to w to write input to the command.
The exec() family of functions enables us to run a different command within the same process. Unlike system() and popen(), exec() does not launch a new shell to run the command. Instead, it replaces the current running program in the process with the new one, so the original program no longer exists after calling exec():
#include <stdio.h>
#include <unistd.h>
int main() {
execl("/bin/ls", "ls", "-l", NULL);
perror("execl failed");
return 1;
}
In this example, the execl() function replaces the current process with the ls -l command, rather than creating a new one. If the execl() call is successful, the original command stops and ls -l takes over. If the command fails to execute for any reason, the program will display an error message using the perror() method.
Additionally, the arguments supplied to execl() include the path to the executable, /bin/ls. The program’s options or arguments are -l and a NULL value to indicate the end of the list.
In this article, we looked at a few ways to execute Linux commands from a C application.
Starting with the system() method, we saw how simple it is to execute commands that don’t require us to interact with their results. The popen() method, on the other hand, offers more flexibility by allowing interaction with the command’s input or output using pipes.
Additionally, the exec() method allows us to replace the current process with a new one, which is helpful when we don’t need to return to the previous application.
Each of these methods has its advantages, depending on the task at hand. For simple tasks, system() is a quick and convenient solution. popen() is useful when we need more control over command execution. Finally, exec() is great when we need to completely replace the existing process with a new command.