So I'm not exactly sure if this is possible, but I would like to use unix's alias command for creating aliases of commands I have created inside of my C program.
So far the only idea I have had to try is system(alias ='someCommand');
This resulted in nothing happening
Is this even possible? Or do I have to essentially create my own alias function for my c program (which is a simple shell program)
Thanks, I'm new to this and would appreciate any insight!
Aliases are meant as shortcuts that you create to reduce your typing when working inside the shell. When you execute a program that you created by compiling your C source code, the shell forks and execs the program. Any changes that you intend to make to the shell happen inside that execed code. As soon as the program is terminated, your changes disappear with it. Hence, what you observe: "Nothing happens".
Related
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.
I'm working on an old C software. There is one ksh script which executes a C program, which then creates some other processes and ends. These processes remain alive.
I'm trying to set an environment variable inside my ksh script, so that it could be accessible in the newly created processes that are still alive.
I have tried this way :
#!/bin/ksh
VARIABLE=value
export VARIABLE
my_c_program
But that doesn't work... I have tried to :
change my ksh script to bash
create a wrapper script that creates and exports the variable and then executes the original ksh script (which just executes the C program)
sourcing my ksh script (or my wrapper script when trying with 2.) instead of executing
it
But nothing from that worked.
The only thing that works for now is when I explicitly, by hand, execute the command :
export VARIABLE
In the current bash terminal.
Why? Isn't it possible to do the export inside a script instead of doing it manually?
Everything is ok actually...
The fact is that the process I thought was the child of the C program executed in my ksh script was the child of another process executed before. The C program was just sending a message via shared memory to tell the other program to execute its child.
So indeed the environment variable never went from my C program to the other's child. The only time when I had that variable set in the child is when I executed the other program (the one which is the real parent of the child) in a shell where the variable was exported.
The code above looks correct and it should work. Another way to do it is:
VARIABLE=value my_c_program
which exports the variable just for the program. Afterwards, the variable will be set but other external processes don't get a copy.
So why doesn't your script work? It's hard to tell but here are some tips to debug the issue:
Use #!/bin/ksh -x to enable debug output. Save the output in a file and then grep VARIABLE to make see what happens with it.
Check for typos.
Another shell script is like an external process. So create a script
#!/bin/ksh
echo $VARIABLE
and call it instead of my_c_program just to make sure passing the variable on works.
Maybe the C does something unexpected. Use a debugger to make sure it does what you expect.
For educational reasons I have to exploit an C-Code
The Programm set the egid first, and then the vulnerability with the system("/usr/bin/..."); Command.
So I made an 'usr' executeable in my Home-Directory and set the Path to the Home PATH=$HOME:$PATH
And I want to change the IFS Variable in the bash to /: export IFS='/'
Unfortunatelly, when i call the C-Programm: my exploit doesn't work
Is anybody able to tell me what is wrong?
Add the IFS as part of your program's call to system(). System executes the code with /usr/bin/sh -c. So you can do similar to what you'd in the shell prompt.
system("export IFS='/'; /usr/bin/cmd");
Note that once the child process is terminated, the IFS set will no longer be available in the parent.
I suppose we are studying at the same university, because I am currently confronted with the same problem. I don't want to give you the whole solution, because that would be too easy =)
Your IFS variable is not ignored, but it doesn't work as you might think. When you call the C-Programm there is an additional output in the shell, which refers to the lesspipe. With the information in this link and this german link you are able to solve the challenge1 ;)
I am wanting to make a terminal app that stores information about files/directories. I want a way to keep the information if the file is moved or renamed.
What I thought I could do is have a function execute before any command is run. I found this:
http://www.twistedmatrix.com/users/glyph/preexec.bash.txt
But I was wondering if this would be a good way to go about it. Or should I do something else?
I would like to call that function from a C program whenever mv is entered I suppose.
If what you're trying to do is attach some sort of metadata to files, there's a much better supported way to do that -- extended attributes.
Another solution might be to use the file's inode number as an index into a database you maintain yourself.
Can you alias the mv command? in .profile or .bashrc
alias mv=/usr/bin/local/mymv
where mymv is a compiled executable that runs your C code function and calls /usr/bin/mv.
precmd and preeexec add some overhead to every bash script that gets run, even if the script never calls mv. The downside to alias is that it requires new code in /usr/local and if scripts or users employ /usr/bin/mv instead of mv it will not do what you want. Generally doing something like this often means there is a better way to handle the problem with some kind of service (daemon) or driver. Plus, what happens if your C code cannot correctly handle interesting input like
mv somefille /dev/null
If you want to run command each time after some command was executed in the terminal, just put the following in ~/.bashrc:
PROMPT_COMMAND="your_command;$PROMPT_COMMAND"
If you want your command to be executed each time before mv is executing, put the following in ~/.bashrc:
alias mv="your_script"
Make sure that your script will execute real mv if needed.
You can use inotify library to track filesystem changes. It's good solution, but once user remove file, it's already gone.
You might be able to make use of the DEBUG trap in Bash.
From man bash:
If a sigspec is DEBUG, the command arg is executed before every
simple command, for command, case command, select command, every
arithmetic for command, and before the first command executes in
a shell function
I found this article when I was forced to work in tcsh and wanted to ensure a specific environemtn variable was present when the user ran a program from a certain folder (without setting that variable globally)
tcsh can do this.
tcsh has special alias, one of which is precmd
This can be used to run a script just before the shell prompt is printed.
e.g. I used set precmd 'bash $HOME/.local/bin/on_cd.sh'
This might be one of the very few useful features in csh.
It is a shame but I don't think the same or similar feature is in bash or other sh derivites (ash, dash etc). Related answer.
I created a little mini shell and it let's the user enter a command like 'ls' and it will list the contents of the directory like it's supposed to using execv() in my code, but that doesn't seem to work for when the user enters something like 'set name="bob"'. I've been looking all over the place for what I should use in my code to execute a set command when the user enters it and the best I can find is system(), but that still isn't working for me. Any ideas?
set is a shell-builtin command, not an external command (indeed it needs to be to have the intended effect, which is to modify a shell variable within the shell process itself).
This means that you need to look for and handle set within your shell itself, by adding the named variable to some internal data structure that tracks shell variables (or updating it if it already exists there).
Since you're doing a fork-and-exec or a system(), the command is really being run in a separate process. What happens in that process (like setting an environment variable) does not affect the parent's environment. (A separate issue is that set doesn't actually create an environment variable. You'd need export in [ba]sh or setenv in [t]csh to do that.)
So you need to code your mini-shell to handle the set command explicitly, rather than passing it off to another program.
You might want to look at setenv(3) and getenv(3). These are functions for changing and reading environment variables from within a C program.