Assignment of variable is not getting picked up in makefile - c

I am using a makefile where there is a line like
VAR=$(MVAR) command1;
Now when command1 executes i want VAR to retain the value what is being assigned by MVAR which is required for the successful completion of command1.
But unfortunately VAR contains some default value while executing command1, ie VAR is not able to hold the value assigned during assignment while executing command1.
if same command i run in any of the shell the value of VAR is retained and command1 gets executed successfully.
Nearly tried everything to run it on makefile.
Can somebody please explain me the reason behind this behavior in gnu makefile and possible solution. I am using Linux as OS and ksh as shell for Makefile.

If you are talking about a command in a rule, just add (or move) a semicolon:
VAR=$(MVAR); command1
But I suspect there may be more involved. If this doesn't work, please give us more context (e.g. the makefile and some information about command1).

what sort of thing are you expecting MYVAR to be set to? If it contains spaces or other characters meaningful to the shell, what you are doing won't work. You could try quoting it:
VAR='$(MVAR)' command1
and see if that works better.
Also, this depends on your shell being a standard POSIX bourne-shell derivative (sh, bash, ksh, zsh all qualify; the Windows cmd processor does not).

Have you tried VAR:=$(MYVAR)? (i.e. := instead of =)
This forces VAR to be assigned the value immediately, rather than being lazily evaluated.

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.

using the Unix alias command in C program

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".

Hooks on terminal. Can I call a method before a command is run in the terminal?

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.

Execute SET command in c program

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.

Anyway to get return value of c program from command line?

I understand if I write a bash script I can get the return value, but is there anyway to get the return value without scripting, and just command line?
Yes, the same way you'd do in a Bash script. Run your program like this:
./your_program; echo $?
In light of the invalidation of the previous answer (good point, Carl Norum), let me re-phrase my comment as an answer:
BASH stores the return value of the previously run command in the variable $?. This is independent of the programming langauge used to write said command (the command can also be a shell internal).

Resources