This question already has answers here:
How do I create an alias where the arguments go in the middle? [duplicate]
(6 answers)
Closed 1 year ago.
I'm trying to do something like this. But it's not working.
$ alias setroot="export ROOT=$1; export PATH=$ROOT/bin:$PATH"
$ setroot /path/to/root
bash: export: `/path/to/root': not a valid identifier
Can someone point out, what is going wrong here?
To clarify, I need ROOT also in my environment.
Alias is literally replaced and $1 is empty, because your interactive shell was started with no arguments and all variables $1, $ROOT and $PATH are expanded when defining your alias, because you used double quotes. So:
setroot /path/to/root
does:
export ROOT=; export PATH=<content_of_ROOT>/bin:<content_of_PATH> /path/to/root
The second argument to second export is invalid identifier - /path/to/root contains /, and variables can't contain /. The content_of_ROOT is the value of ROOT when defining alias, not upon using it.
Use a function. Check your scripts with shellcheck.
Related
This question already has answers here:
Execute command containing quotes from shell variable [duplicate]
(2 answers)
Closed 1 year ago.
$ cat test.sh
#! /bin/bash
run="/Applications/YubiKey\ Manager.app/Contents/MacOS/ykman openpgp"
$run info
$ ./test.sh: line 5: /Applications/YubiKey\: No such file or directory
Is there a way to handle space in path to executable (/Applications/YubiKey\ Manager.app/Contents/MacOS/ykman) and space between path and argument (…/ykman openpgp)?
You need the quotes or the backslash, not both.
run="/Applications/YubiKey Manager.app/Contents/MacOS/ykman openpgp"
or
run=/Applications/YubiKey\ Manager.app/Contents/MacOS/ykman \openpgp
Update: as this is a command name and an argument, not a single path name, you should be using either an array:
run=("/Applications/YubiKey Manager.app/Contents/MacOS/ykman" openpgp)
"${run[#]}" info
or better yet, define a function instead of a variable:
run () {
"/Applications/YubiKey Manager.app/Contents/MacOS/ykman" openpgp "$1"
}
run info
This question already has answers here:
How to store curly brackets in a Bash variable
(2 answers)
Closed 4 years ago.
I'm trying to use this variable
MediaExt="*.{mp4,mkv,avi}"
in this command
mv ${MediaSource}/${MediaExt} ${UploadDir}
but it doesn't seem to work.
Could someone help me, please? Thanks!
A command in bash is parsed in several passes. The pass that decides whether globbing (expanding *, or *.{mp4,mkv,avi}) should be performed, is occurring before the pass that expands the variables. Once the variables are expanded, there are candidate for globbing, but the decision that no globbing is required has already been made
It will work if you write the expression as:
mv ${MediaSource}/*.{mp4,mkv,avi} ${UploadDir}
You'll probably find some advise that you can use eval. Please don't!
This:
eval mv ${MediaSource}/${MediaExt} ${UploadDir}
will execute as you intended, but eval can be dangerous if you don't control the values of the variables. For example, if UploadDir could be set to:
UploadDir="somedirectory; rm -rf ~"
then eval will execute your request as two statements and remove all your files.
This question already has answers here:
What does "export" do in shell programming? [duplicate]
(3 answers)
Closed 2 years ago.
If we set custom environment variables in .bashrc like the following:
TMP_STRING='tmp string'
It seems like this variable is not directly accessible from the bash script.
#!/bin/bash
echo $TMP_STRING
I tried the following, but it also doesn't work:
#!/bin/bash
source ~/.bashrc
echo $TMP_STRING
Could you suggest what would be the correct way in this case?
Thank you!
Just VAR=value defines a shell variable. Environment variables live in a separate area of process memory that is preserved when another process is started, but are otherwise indistinguishable from shell variables.
To promote a variable to an environment variable, you must export it.
Example:
VAR=value
export VAR
or
export VAR=value
If you put the above into .bashrc, the above value of $VAR should be available in the script, but only if it's run from the login shell.
I would not recommend sourcing .bashrc in the script. Instead, create a separate file named something like .script.init.sh and source that:
# script init
TMP_STRING='tmp string'
Your script:
# script
. ~/.script.init.sh
If this value must be available to any process spawned by the script, prefix it with export :
# script init
export TMP_STRING='tmp string'
This question already has answers here:
Setting an argument with bash [duplicate]
(2 answers)
Closed 5 years ago.
I have to use a bash script (I'm not familiar with bash) for submitting a HPC job. The job-submission script template sets the command and options and then combines them in the end:
input="file_name"
name="simulation1"
application=my_app
options="in=$input.h5 out=$name.h5 param1=foo"
cmd="$application $options"
this all works okay, i.e. eval $cmd executes
my_app in=$input.h5 out=$name.h5 param1=foo
until I need the character '>' in the options. In particular, I want to add the option absrad="mass>1?H:0", but if I simply set
options="in=$input.h5 out=$name.h5 param1=foo absrad=mass>1?H:0"
then bash truncates that at the '>', so that eval $cmd executes
my_app in=$input.h5 out=$name.h5 param1=foo absrad=mass
instead. How to fix that such that eval $cmd executes
my_app in=$input.h5 out=$name.h5 param1=foo absrad="mass>1?H:0"
EDIT. Note that this is similar to, but not a duplicate of this post, where a single-quoted argument is the problem. Moreover, the answers there only consider solutions using an array for the options. I would like alternatives w/o array.
You could always use an array for options:
declare -a options=("in=$input.h5" "out=$name.h5" "param1=foo" "absrad=\"mass>1?H:0\"");
declare -a cmd=(my_app "${options[#]}");
Then when you want to expand cmd the following should give you the correct expansion:
"${cmd[#]}"
Additionally, this gets rid of the need to use eval, which I tend to avoid whenever possible.
This question already has answers here:
Echoing a tilde to a file without expanding it in Bash
(3 answers)
Pass a special variable (~ tilde) to Java program
(1 answer)
Closed 5 years ago.
I have a simple bash script that can accept arguments that it will be treating as text strings, nothing more.
If I give it ~, without quotes, then the home directory /home/users/me is what's parsed. Quote it, "~", it's fine. The character "~" is what I want, not the home path.
Is there any way I can ensure an un-quoted ~ is treated exactly as the character "~", not the home directory alias?
The bash shell is expanding the ~ on the command line before the argument is passed to your script.
There might be a bash option that you can change in your shell, but that would affect everything in your shell, which doesn't sound like what you want.
The short answer I think is no. There's nothing you can do in your script to change how the parent shell expanded any arguments before passing them to your script.