How can I execute a cat command in a execlp in C? - linux

I'm trying to execute commands that are passed from the terminal to argv seperated by : to be more specific cat nevermind : grep left : wc -c.
tabCommand is an array that contains each command so cat nevermind,grep left,wc -c
With printf I can confirm that tabCommand[i-1] is indead equal to cat nevermind but the output I get is Error: No such file or directory
if (execl(tabCommande[i-1],tabCommande[i-1], (char *)NULL) == -1) {
error_and_exit();
}
If someone can help me find the issue I would really appreciate it.

With the comments I got in my post I managed to find my problem
execlp("/bin/sh","sh","-c",tabCommande[i], (char *)NULL) works because I need to use the full path.
If I do execlp(tabCommande[i],tabCommande[i], (char *)NULL) it won't work because im not using the full path of each command so simply giving cat to execlp won't work.
found this answer thanks to waltinator I'm new to stack so i dont know how to give you the credit

Related

Execute the output of previous command line

I need to execute the result of a previous command, but I don't know how I can process.
I have a first command that returns an instruction to log in to the server and then I want to execute it just after.
my-first-command returns: docker login ...
For example:
> my-first-comnand | execute the result of my-first-command
This should do it I believe.
my-first-command | bash
I use $(!!) for this. As Charles points out, this may not be what everyone wants to do, but it works for me and suits my purpose better than the other answer.
$ find ./ -type f -name "some.sh"
$ $(!!)
!! is a variable that holds the last command, and putting into $( ) makes it get executed.
This is also useful for taking other actions on the output, since $( ) is treated as a variable.
Most handy way is to use backticks `your_command` to execute your sub-command inline and immediately use output in your main command.
Example:
`find ~/Library/Android/sdk/build-tools/* -d 0 | tail -1`/zipalign -f 4 ./app-release-unsigned.apk ./app-release.apk
In this example I firstly find the correct directory from where I will execute zipalign. There could be several directories as in my case (find returns two directories) so I getting last one using tail. And then I'm executing zipalign directly using previous result as path to correct zipalign binary.

Linux command line open any directory

I'm currently using the Linux command line and was just wondering whether there is a quick command you can enter into the console to open any of a given directory.
I'll give you an example of what I mean.
say in a directory ligands/
we have:
ligand_1993324
ligand_1993444
ligand 1993255
shoe_lace
water_bottle
Lets just say there are 100000 of these very similar directories. Because I'm lazy I just want to pick any random one of these, but it has to begin with ligand_199 for example.
Please not I'm trawled through the manual and can't find anything, I've also looked at other stacks, any help would be great!
There are a couple of versions of a program called variously "randomline" or "randline" about. This version shows its age (it's in Perl).
#!/usr/bin/perl
while(<>)
{
push #lines, $_;
}
$randline = $#lines;
$randline = rand($randline);
print $lines[$randline];
Given this in a file ~/bin/randomline, then your task reduces to the following, assuming that you want to open the file with vim:
vim $(ls ligands/ligand_199* | ~/bin/randomline)
You can use following:
files=(/my/dir/*)
file=`printf "%s\n" "${files[RANDOM % ${#files[#]}]}"`
cat file
Maybe something like
number=$(((RANDOM%10000)+1)) && emacs -nw "ligand_199$number" ?

Lubuntu: Using .sh script as a keybind, code works, executing script gives errors

This is my first ever post on stackoverflow, hope I don't break any rules. I'm a complete Linux newbie (installed Lubuntu 14.04 64bit last night) so be duly warned.
In short, I'm trying to get my laptop touchpad toggle to work (Fn+F3 on my Inspiron5110). I have a bash script:
#!/bin/bash
if [ $(synclient -l | grep TouchpadOff | awk '{print $3}') == 1 ] ; then
synclient touchpadoff=0;
else
synclient touchpadoff=1;
fi
I got it from http://crunchbang.org/forums/viewtopic.php?id=10996 . If I paste the script code in the terminal and execute it, it works (touchpad goes on/off). However, I want to bind it to a key so in my lubuntu-rc.xml I've added the following:
<!-- disable touchpad -->
<keybind key="XF86TouchpadToggle">
<action name="Execute">
<command>/usr/local/bin/touchpad.sh</command>
</action>
</keybind>
When I press the necessary key combo however I get "Failure to execute child process "/usr/local/bin/touchpad.sh" (No such file or directory)". However I can see in this directory, both in the file manager and when I use ls in the terminal that the file is there:
/usr/local/bin$ ls -l
total 4
-rwxrwxr-x 1 paspaldzhiev paspaldzhiev 145 юни 2 22:54 touchpad.sh
I used chmod +x touchpad.sh to make it executable.
Now, where this gets even more confusing:
If I use bash /usr/local/bin/touchpad.sh I get:
paspaldzhiev#areuexperienced:/usr/local/bin$ bash touchpad.sh
touchpad.sh: line 6: syntax error near unexpected token `fi'
touchpad.sh: line 6: `fi'
Though as I've said above I know for a fact that the code works if I just paste it in the terminal.
Further, if I use ./touchpad.sh I get :
paspaldzhiev#areuexperienced:/usr/local/bin$ ./touchpad.sh
bash: ./touchpad.sh: /bin/bash^M: bad interpreter: No such file or directory
Just to note that I'm not very sure what the difference between bash touchpad.sh and ./touchpad.sh is in terms of execution, it's just that my more Linux-savvy friends told me to try these :D.
In any case, I have no idea how to proceed henceforth, could anyone please shed a light on what I'm doing wrong?
Thank you very much!
The ^M in your last error msg is your big hint ; -). Somehow you have used a windows editor, file transfer or something. Try dos2unix touchpad.sh. It will remove all the CR (^M) chars from end of lines. It should work then. Good luck. – shellter
There is no need for script, since there is no need for if instruction.
Place this piece of code in your lubuntu-rc.xml
<keybind key="XF86TouchpadToggle">
<action name="Execute">
<command>synclient TouchpadOff=$((1-$(synclient | grep TouchpadOff | awk '{print $3}')))</command>
</action>
</keybind>

How to make separate strings of a variant in shell script

#! /bin/sh
VAR=(fdf fef fef)
for i in ${VAR}; do
echo i;
done
Code above has errors. I want to make shell take VAR as a separate string array, and get the output like this:
fdf
fef
fef
how to make it happen ? Thanks !
Try this:
VAR=(aa bb cc)
for i in "${VAR[#]}"
do
echo $i;
done
More info in this article.
The proposed solution only works when using bash. He must also have changed or removed the shebang, otherwise you'll get: syntax error: unexpected "(".
See also his follow up question: How come using ./shell.sh get error but . shell.sh works

How to check if command is available or existant?

I am developing a console application in C on linux.
Now an optional part of it (its not a requirement) is dependant on a command/binary being available.
If I check with system() I'm getting sh: command not found as unwanted output and it detects it as existent. So how would I check if the command is there?
Not a duplicate of Check if a program exists from a Bash script since I'm working with C, not BASH.
To answer your question about how to discover if the command exists with your code. You can try checking the return value.
int ret = system("ls --version > /dev/null 2>&1"); //The redirect to /dev/null ensures that your program does not produce the output of these commands.
if (ret == 0) {
//The executable was found.
}
You could also use popen, to read the output. Combining that with the whereis and type commands suggested in other answers -
char result[255];
FILE* fp = popen("whereis command", "r");
fgets(result, 255, fp);
//parse result to see the path of the bin if it has been found.
pclose(check);
Or using type:
FILE* fp = popen("type command" , "r");
The result of the type command is a bit harder to parse since it's output varies depending on what you are looking for (binary, alias, function, not found).
You can use stat(2) on Linux(or any POSIX OS) to check for a file's existence.
Use which, you can either check the value returned by system() (0 if found) or the output of the command (no output equal not found):
$ which which
/usr/bin/which
$ echo $?
0
$ which does_t_exist
$ echo $?
1
If you run a shell, the output from "type commandname" will tell you whether commandname is available, and if so, how it is provided (alias, function, path to binary). You can read the documentation for type here: http://ss64.com/bash/type.html
I would just go through the current PATH and see whether you can find it there. That’s what I did recently with an optional part of a program that needed agrep installed. Alternately, if you don’t trust the PATH but have your own list of paths to check instead, use that.
I doubt it’s something that you need to check with the shell for whether it’s a builtin.

Resources