Invoking a C executable with two parameters from a Script - c

I want to invoke a C executable with two arguments both of type string from a script. Am working with busybox shell. There is a script that is called whenever a USB device is plugged. Now I want to invoke my C executable from that script. I tried calling it with /usr/bin/myExecutable param1 param2 & but no use. It is not being called. How can I invoke the C executable from the busybox shell script?

There could be many reasons behind this. I mean what myExecutable program does. Does
it print something on the standard output(terminal)or this program is written to do
some background job.
In any case we can check the status of the last command executed under shell. shell
store the information in the special variable $?. If the last command was successful
it would return 0 otherwise it would return >0.
If possible, please share the output of the following command from your machine.
$/usr/bin/myExecutable param1 param2 &
$echo $?

Related

(LLDB on MacOs Catalina) Shell Expansion Failed

When trying to use the r or run commands in lldb I get an error like this: error: shell expansion failed (reason: invalid JSON). consider launching with 'process launch'.
It works when I just use process launch but I really do not feel like doing that.
Is there any way I could make either an alias or make shell expansions not fail?
The way lldb does shell expansion is to run a little tool called lldb-argdumper (it is in Xcode.app/Contents/SharedFrameworks/LLDB.framework/Resources on macOS) with the command arguments that you passed. lldb-argdumper wraps the contents of argv as JSON, and writes that to stdout. lldb then parses the JSON back into args and inserts the args one by oneinto the argc/argv array when it launches the process.
Something in the output is not getting properly wrapped. You can probably see what it is by looking at the output of lldb-argdumper with your arguments. Whatever it is, it's a bug, so if you can reproduce it please file with your example with http://bugs.llvm.org.
(lldb) command alias run-no-shell process launch -X 0 --
will produce an alias that doesn't do shell expansion. You can also put this in your ~/.lldbinit.
I ran into this recently. TL;DR: make sure your shell does not echo anything during initialization. Run <your-shell> -c date to confirm; only the date should be printed.
The problem was that my shell's initialization file was echoing some stuff, which was getting prepended to lldb-argdumper's JSON output. (lldb doesn't run lldb-argdumper directly; it invokes your default shell to run lldb-argdumper.)
Specifically, I use fish as my shell, which does not have separate initialization paths for interactive and non-interactive sessions. (See this issue for discussion of whether this is good.) bash and zsh have separate init files for interactive/non-interactive sessions, which makes avoiding this problem slightly easier.

How to tell if a shell command is written in Bash or C?

I'm using macOS and I noticed (via a separate article) that the cat command is written in C. But I'm sure I've read elsewhere that some shell commands (builtins?) are written in Bash.
How can you tell the difference?
UPDATE: seems I was misinformed and that no builtin commands are written in bash. What I must have read was something related to an external executable.
Use the 'file' command to determine the type of file.
Built-ins are not written in bash. The are intrinsically part of the command interpreter (which is often bash). Example: 'cd'. The 'file' command will not be able to find a built-in and will give an error.
the difference between a bash builtin and an executable is that when calling from a bash process a builtin is a function call whereas an external command forks a new process (if not in background waits for termination).
note the overhead of calling a new process
for((i=0;i<1000;i++)); do /bin/echo -n ; done
to know if a command is a builtin or an executable you can use type
type cat
type -a echo
to explicitly call echo builtin
builtin echo
to explicitly call echo command
command echo
note commands that changes process environment like cd can't be an executable because calling a sub process can't change caller's environment.

Need to get C program name inside shell script

I have an occasion where a C program invokes a shell script, which in-turn does some copying stuff from the CD mount location to an installation directory.
Now my question is that, is there a straightforward approach to get the absolute path of this C program inside this shell script ?.
I tried a couple of approaches that includes using "$(ps -o comm= $PPID)" from within the script, but nothing did work out till now. I know that I can create a temporary file from the C program which contains its own name (argv[0]) and then make the shell script to read that file, but I don't want to follow that approach here.
Of course, it can be passed as an argument to the script, but I was thinking why the bash built-in macros or something cannot be used here
On linux there is a /proc/self/exe path that points the absolute path of the current executed file. So you can push an environment variable that contains the path before spawning the shell. Something like:
readlink("/proc/self/exe",...,buf);
putenv("MYEXE",buf);
system("thescript");
and accessing the variable in the script:
echo $MYEXE
Before running a foo command you could use which like
fooprog=$(which foo)
to get the full path of the program (scanning your $PATH). For example which ls could give /bin/ls ....
On Linux specifically you could use proc(5).
In your shell process (running bash or some POSIX compliant shell) started by your C program, $PPID give the parent process id, hopefully the pid of the process running your C program.
Then the executable is /proc/$PPID/exe which is a symbolic link. Try for example the ls -l /proc/$PPID/exe command in some terminal.
(notice that you don't run C source files or stricto sensu C programs, you often run some ELF executable which was built by compiling C code)
You might have weird cases (you'll often ignore them, but you might decide to handle them). Someone might move or replace or remove your executable while it is running. Or the parent process (your executable) died prematurely, so the shell process becomes orphan. Or the executable removed itself.

How shell commands execute

I am a newbee and looking for some info.
Thanks in advance.
What is difference between echo "Hello World!" and a c-program which prints "Hello World!" using printf.
How do shell commands get executed. For example if I give ls it lists all the files in the directory. Is there executable binary which is run when we enter ls in shell.
Please let me know if you guys have any links or source to get this clear.
There are two main types of "commands" that the shell can execute. Built-in commands are executed by the shell itself - no new program is started. Simply typing echo in a shell prompt is an example of such a built-in command.
On the other hand, other commands execute external programs (also called binaries) - and ls is an example of this kind of command.
So, if you run echo in a shell, it's executed by the shell itself, but if you write a C program that performs the same action, it wil be run as an external program. As a matter of fact, most Linux systems come with such a binary, located at /bin/echo.
Why does it sometimes make sense to have both a built-in command and a program to accomplish the same task? Built-in commands are faster to execute as there is some cost involved in running an external program. But built-ins have some drawbacks, too: they can't be too complex as this would make the shell big and slow; they can not be upgraded separately from the shell and from each other; finally, there are situations where an external program which is not your shell would like to run an application: it can run external programs but it can't execute shell built-ins directly since it's not the shell. So sometimes it makes sense to have it both ways. Apart from echo, time is another example of this double approach.
The shell is just a user level way of interacting with the operating system, or the kernel. That's one of the reasons it's called a shell. The shell itself (sh, csh, tcsh, ksh, zsh, bash, etc...) is essentially just a binary the operating system executes to allow you to execute other binaries.
It generally gives a lot of other functionality though like built in functions (echo, fg, jobs, etc...), an interpreted language (for x in ..., if then, etc...), command history, and so on...
So, any text entered into the shell (like echo), the binary (or process) interprets and runs the corresponding functions in its code. Built in functions (like echo) don't need to create a new process, but if the text is interpreted as a request to execute a binary (vim, emacs, gcc, test, true, false, etc...) the shell will create a new process for it (unless you prefix it withexec), and execute it.
So, echo "Hello World! just runs code in the shell (process). A printf("Hello World!") would be in seperate binary that the shell would create a new process for (fork), and have the operating system execute (exec).

Building simple shell script which executes program passed as argument

I am building a program which helps in memory debugging of C programs. I call
execlp("gnome-terminal","gnome-terminal","-e",command,(char*)0);
to open a new terminal window where the program to be debugged runs. I do this to not have my debugging info intermixed with the users program output. Because I need to set up an environmental variable before running the users program, command var is actually the name of the shell script where I pass the users program as the first arg.
Here is my script:
#!/bin/bash
export LD_PRELOAD="./mylib.so"
$1
This works fine for programs with no arguments but what happens if the user also supplies args with his program?
For example I wish to call my script like that :
myScript.sh usersProgram arg1 arg2 etc
How can I correctly run the users program inside the script and pass all the arguments to it?
Thank you
Use "$#", which will handle all arguments properly.
Assuming that args to program always start from the 2nd arg, I'd suggest doing it like this:
#!/bin/bash
PROG=$1
shift
$PROG "$#"
Practically, just specifying "$#" instead of the three lines above will also work. But this way, you can easily do some manipulation based on $PROG before actually executing it.

Resources