How can I execute the following command using execvp, if it's possible:
"ls | tee ~/outputfile.txt"
I've tried to run the following code but got this message: execvp() not expected: No such file or directory
I'm not sure for the cause of this issue,
I can't execute this command because this is concatenation command ?
#include <unistd.h> // execvp()
#include <stdio.h> // perror()
#include <stdlib.h> // EXIT_SUCCESS, EXIT_FAILURE
int main(void) {
char *const cmd[] = {"ls | tee ~/outputfile.txt", NULL};
execvp(cmd[0], cmd);
perror("Return from execvp() not expected");
exit(EXIT_FAILURE);
}
In the bottom line, want to write the output of the command 'ls' to a file in my code.
Thank you in advance!
You can't use execvp (or any exec* function family) like that.
First of all, the first argument must be the path to the executable file.
I doubt you have an 'ls | tee ~/outputfile.txt' executable somewhere on your computer.
You have 'ls' or 'tee' probably, but not 'ls | tee ~/outputfile.txt'.
Secondly : exec* function family can't do nativly piping (the '|' part) : you have to do it yourself.
An example is the following :
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char *const cmd[] = {"ls", "/home", NULL};
execvp(cmd[0], cmd);
perror("Return from execvp() not expected");
exit(EXIT_FAILURE);
}
That will do a ls in "/home".
It's up to you to pipe it in another execve : this can greatly help you.
If you just want to execute your command line wthout any regard for security, you can use "system"
Related
I'm creating a small unix shell, execve has an issue with sed. When I execute sed -e 's/Roses/Turnips/' the command fails with execve.
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
int main(int ac, char **av, char **envp)
{
char *argv[] = { "/usr/bin/sed", "-e", "'s/Roses/Turnips/'", 0 };
execve(argv[0], &argv[0], envp);
fprintf(stderr, "Failed!\n");
return -1;
}
Error:
/usr/bin/sed: -e expression #1, char 1: unknown command: `''
Get rid of the single quotes around the s/// argument. Those are part of shell syntax, not sed syntax.
char *argv[] = { "/usr/bin/sed", "-e", "s/Roses/Turnips/", 0 };
execve executes the program directly, it doesn't use a shell. Every argument is sent literally to the program, so no escaping or quoting is needed as when running a program in the shell.
That problem arises inside of sed because it doesn't want your single quotes.
You'd use those single quotes in a shell to prevent it from interpreting the sed command, but the shell would ultimately remove those quotes, which is what you need to do also.
I´m trying to execute the next linux command
cat file_a file_b file_c | wc –l > result.txt
in a C program, but I´m not able to do it properly. I have very low level of C programming, and I would like to see how to make that command works in a C program.
This is the code I developed without success:
void main() {
execlp("/bin/sh", "/bin/sh", "-c", "cat file1 file2 fileN | wc –l > lines.txt", 0);
}
I follow your example.
Its results:
implicit declaration of function 'execlp' is invalid in C99
And some other warning errors.
But I think it would be better if you use the system() C-function, here is what I've done:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
system("cat filea fileb filec | wc -l > result.txt");
return EXIT_SUCCESS;
}
After compilation that works!
If you want to run just a command without needing to read the resulting output, you could use the C-function system(), but if you want to run it getting its results, you should use popen().
system()
popen()
I'm currently trying to change the process name of a process so I can read the more easily with htop, top, .... I want to LD_PRELOAD this code into another process so it gets renamed by an environemt variable.
I found a lot of stuff in the internet, but nothing works:
prctl(PR_SET_NAME, "Test");
This does not work because htop is not honoring the name.
Nginx setproctitle (Link) doesn't work as well, because it strips the parameters (which are needed by the process).
I tried everything I found and now I'm out of ideas.
Is this even possible in linux? And how?
Just run your program by shell script or your program through exec and pass desired name as argv[0]:
#/bin/bash
exec -a fancy_name a.out ...
or C/C++:
execl( "./a.out", "fancy_name", ... );
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#define NEW_NAME "hello_world"
int main(int argc, char **argv) {
if(strcmp(argv[0], NEW_NAME)) {
argv[0] = NEW_NAME;
execv("/proc/self/exe", argv);
fputs("exec failed", stderr);
return 1;
}
while(1) // so it goes to the top
;
}
For a project, I'm supposed to pipe the output of a command to my C program (called execute), which will then execute that command.
For example, running this:
echo ls -lR /usr | ./execute, will take the output (ls -lR /usr) and pass it into my C program which will then execute ls -lR /usr.
According to the directions, I'm supposed to use execvpe() to do the actual execution of the program, however I can't find any documentation that makes sense, nor can I get it to work without getting these errors:
execute.c: In function ‘main’:
execute.c:98: warning: implicit declaration of function ‘getenv’
execute.c:98: warning: assignment makes pointer from integer without a cast
execute.c:106: warning: implicit declaration of function ‘execvpe’
My professor said that I have to #include <unistd.h>, and <stdio.h> which I did, parse the input to my program (which I did), and then do this:
int main(void) {
char *path;
path = getenv("PATH");
char *envp[] = {path, NULL};
// the initialized array below could change normally.
// below is just an example
char *tests = {"ls", "-lR", NULL};
int ret = execvpe("ls", tests, envp);
if(ret == -1) { printf("error\n"); }
return 0;
}
He then stated that execvpe should find the path correctly and execute everything. But no matter what I keep getting these warnings. Running the program and ignoring the warnings immediately seg faults. Does anyone know how execvpe works or how I can fix this?
This code should work, assuming your system has execvpe() at all:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main(void) {
char *path = getenv("PATH");
char pathenv[strlen(path) + sizeof("PATH=")];
sprintf(pathenv, "PATH=%s", path);
char *envp[] = {pathenv, NULL};
char *tests[] = {"ls", "-lR", NULL};
execvpe(tests[0], tests, envp);
fprintf(stderr, "failed to execute \"%s\"\n", tests[0]);
return 1;
}
Updated to format PATH=$PATH in the environment.
It fixes the compilation error on tests, uses tests[0] as the command name to execvpe(); it reports the error on standard error; it includes the name of the command that was not executed; it returns a failure status (non-zero) when exiting; it notes that execvpe() only returns if it fails so it isn't necessary to test what its return status is. It does not include the system error message in the error message, but you could modify the code to include <errno.h> and <string.h> and use errno and strerror() to report that information too.
#include<stdio.h>
#include<unistd.h>
#include<string.h>
#define MAXLINIE 100
main(int argc, char* argv[]) {
if (fork()==0){
execl("/bin/> temporar.txt", "/bin/> temporar.txt", ">temporar.txt", NULL);
}
}
Basically, what I am trying to do is creating a file using a process in unix, here is my code, but for some reason it does not work, I do not really understand the execl command and why the first two parameters have to be the same: execl("/bin/ls", "/bin/ls", "-l", NULL); this is working well, could someone help me ?
Thanks a lot!
first search whereis is touch:
~$ whereis touch
touch: /bin/touch /usr/bin/touch /usr/bin/X11/touch
use: int execl(const char *path, const char *arg, ...);
execl("/bin/touch", "touch", "filename", NULL);
^ ^ ^ ^
command command argument
path name
arg 0 arg 1
Consider use system() instead:
system("/bin/ls -l > temporar.txt");
Or using execl call /bin/sh to redirect stream:
execl("/bin/sh", "/bin/sh", "-c" , "/bin/ls -l >temporar.txt", NULL);
First parameter of execl is a command to execute, second is a first parameter to be passed to command (argv[0]), third and next - other arguments argv[1] ...