This question already has answers here:
how to run python script without typing 'python ...'
(5 answers)
using alias in shell script? [duplicate]
(7 answers)
Can the child process affect parent process' environment?
(3 answers)
Changing a directory of the parent shell [duplicate]
(2 answers)
Closed 3 years ago.
I am working on a class project that requires a makefile and needs to parse input below as an example
make
myapp arg1 arg2 arg3 arg4....
So I create a myapp.py
import sys
program_name = sys.argv[0]
arguments = sys.argv[1:]
count = len(arguments)
for x in sys.argv:
print("Argument: ", x)
I create a Makefile
all:
alias testapp="python3 myapp.py"
Doing this it should allow me to write
$ testapp arg1 arg2 arg3...
If I manually input the alias statement into the terminal it works correctly, but when run in a Makefile,
it doesn't work for me. Any ideas on a workaround for this? thank you in advance
This is not specific to make.
Aliases are only supported in interactive shells by default.
Also, any code run in a subprocess (i.e. any command you run which is not a shell builtin) will be unable to change anything in the parent process (aliases, variables, etc). So you can't change the behavior of your current shell with make, or a script, or any other external command (except if you cause the shell to cooperate, for example by using a shell builtin which evaluates code printed by a subprocess - eval and source are two common ways to make the shell cooperate).
A simple way to accomplish what you want is to make sure myapp.py has a valid shebang as its very first line
#!/usr/bin/env python3
then make the file executable;
chmod +x myapp.py
then create a symlink to it with the name you want to use in a directory which exists on your PATH. Assuming $HOME/bin already exists and is already on your PATH, simply
ln -s $(pwd)/myapp.py $HOME/bin/testapp
in the directory where you have myapp.py.
Aliases have some drawbacks; maybe prefer shell functions where you could have used an alias.
Related
This question already has answers here:
Source files in a bash script
(2 answers)
Can I export a variable to the environment from a Bash script without sourcing it?
(13 answers)
Closed 2 years ago.
Here is what I have:
script_1.sh
echo "HELLO FROM script_1.sh"
./scripts/script_2.sh
echo $MY_VARIABLE
script_2.sh
echo "HELLO FROM script_2.sh"
export MY_VARIABLE="MY_VALUE"
Here is what it logs when I run script_1.sh:
HELLO FROM script_1.sh
HELLO FROM script_2.sh
"" // EMPTY LINE INSTEAD OF "MY_VALUE"
What am I doing wrong?
Variables are exported from a parent to a child, not vice versa. script_2.sh is called in a different shell whose environment doesn't propagate back to the parent shell.
Source the script (using the .) to call it in the same shell. You then don't even need to export the value.
. ./scripts/script_2.sh
environment variables are inherited down the call chain. they are not returned up to the caller.
in other words: a called script might inherit the variables of the caller. but the caller will not get the variables of the called script.
in you simple example the easiest solution is to "source the script"
. ./scripts/script_2.sh
(the dot is the command to source a script)
sourcing is not a new step in the call chain. instead the sourcer and sourcee share the same environment. for more explanation on the difference of executing and sourcing see here: https://superuser.com/questions/176783/what-is-the-difference-between-executing-a-bash-script-vs-sourcing-it/176788#176788
there are other options but they are more complicated and error prone. it seems that you are starting to learn shell scripting. so learn the difference of sourcing and executing and the implication on the environment for now. if you need other options later then come back and ask another question.
This question already has answers here:
Shell script current directory?
(7 answers)
Closed 2 years ago.
I want to be able to execute a bash script located in my home directory with the command ~/script_name.sh from any directory and then in the script, get the directory that it was ran from.
eg. I'm in the directory /foo/bar/baz, and execute /foo/script.sh, and it prints out /foo/bar/baz
pwd and $0/$BASH_SOURCE give me the directory my shell starts in and the path to the script in my home directory respectively.
Instead of invoking the external command pwd, consider using $PWD instead. If you want to protect against some rogue code having explicitly changed PWD, do a cd . (which is an internal command) first, which restores PWD to the correct value.
This question already has answers here:
Why do you need ./ (dot-slash) before executable or script name to run it in bash?
(9 answers)
Closed 5 years ago.
When I executeinit-hooks I get
bash: init-hooks: command-not found
here are the contents of init-hooks:
#!/bin/bash
set -e
printf '\ncopying hooks\n\n'
cp ./hooks/* ../../.git/hooks
When I execute cp ./hooks/* ../../.git/hooks from bash directly execution is successful.
(note this is the same command as what is in the script)
Proof of the files are in the directory and the results of execution:
Why does my script behave differently than the command/why is my script not found?
On the Linux systems (where bash comes from) the current directory is usually not included in the path for security reasons.
Run echo $PATH to check what directories are used to search for executables when they are provided in the command line without a path. The current directory (.) should not be there.
Run the script as ./init-hooks and bash will find it.
I suugest to run it following way
./init_hooks
or put fully qualified file name.
make sure to make the script executable
chmod +x ./init_hooks
This question already has answers here:
unix command line execute with . (dot) vs. without
(5 answers)
Closed 7 years ago.
In UNIX, when you want to run a shell script located in pwd, you do:
./somescript.sh
But there is also:
. somescript.sh
What does the second command do?
The dot is an alias for the command "source": http://ss64.com/bash/source.html.
The main difference is that the first syntax tries to execute the script by running some interpreter for it (as determined by the hashbang magic header value). For a shell file, the interpreter is usually bash or sh, and so your shell will launch a new shell process as a subprocess and pass the script as a parameter. The script will run isolated in this subprocess. If it for instance sets an environment variable, it will beisolated to the subprocess and disappear as the subprocess exits
Sourcing the file, OTOH, instructs the current shell to read the instructions in said file. In this case changes will modify the current environment. Changed environment variables will be visible after command completion.
Sourcing only works for shell scripts written for the current shell. Execution works for any type of runnable script/program/executable file.
This question already has an answer here:
Best way to set environment variables in calling shell
(1 answer)
Closed 8 years ago.
I have a script "set_var.sh" written like this
#!/bin/bash
export NAME=release
export ROOT=/Volumes/name/dev/release
but if I run this set_var.sh from terminal, afterward I issue set command to check variables I could not find NAME and ROOT var be set.
I am wondering what is wrong in my case.
it was set in sub-shell.
you need
source set_var.sh
If you simply run set_var.sh, it runs in its own shell which exits, losing the variables that were set.
If you want to change variables in your interactive shell, you can use:
source set_var.sh
or the shorthand,
. set_var.sh
This will execute the lines of the script as if they were typed into your interactive shell.
Note that when you "source" a file this way, it does not require the "shebang" on the first line.
Note also that this is feature exists in Bourne shell as well, but only in the short-form version.