I'm trying to reassign the value of the positional command line argument $1 to another variable to use elsewhere in the script, but it never works. I have put the following code in a new script and found that the value of the new variable is always blank.
dirname = $1
echo "This is \$1:$1"
echo "This is \$dirname:$dirname"
The output of this after running ./test.sh someval is:
This is $1:someval
This is $dirname:
As you can see, 'dirname' is blank, even after being assigned the value of $1. I'm new to bash so likely missing something. Any help is appreciated.
Assignments cannot have whitespace around the =. An assignment is a single word containing a =: the name precedes the (first) =, and the value follows it.
dirname=$1
Related
I'm writing a shell script for an assignment. The script is supposed to read regex argument and then use that regex. The problem is, if the user doesn't use single/double quotations then the regex will be evaluated before I need it to be evaluated.
Here's an example; let's say that the user executed the script and passed *f* as an argument, and the code has the following lines:
arg=$1 #*f*
echo "$arg"
In the above example echo returns a file name in the current directory that contains the regex *f*. I need echo to print *f*. It works if the user passes '*f*', but is there no other way?
I can not understand this line in one of old scripts in my project :
USER=${1:-`id -un`}
It's a bash parameter expansion pattern.
The given statement indicates:
If the value of $1 (the first positional parameter (argument)) is unset or null then the output of the command id -un will be set as variable USER
If the parameter $1 is set and not null then the expansion of $1 will be set as parameter USER.
Also the variable USER should be set session wide upon login, unless you have a very good reason you should not modify it directly. You can use a different variable name in your script as a solution then.
Check the Parameter Expansion section of man bash to get more idea.
Looking at the manual page for id (man id), the command id -un will return the actual name of the user.
The format :- uses what's on the right only if what's on the left isn't set. More can be learned about this syntax here.
Therefore, the code you provided is essentially saying default to user, but override the $USER variable to the value of $1 if it is provided.
Parse it this way:
The ${} tells you it is a parameter expansion
The :- is use a default value of the Right Hand of the :- if the Left Hand is unset
The backticks around the RH runs that command
Example:
$ sv="set v"
$ echo ${sv:-`whoami`}
set v
$ echo ${not_set:-`whoami`}
dawg
There are other forms, including:
${parameter:?word} display an error if the parameter is unset,
$ echo ${not_set:?'is not set to anything'}
-bash: not_set: is not set to anything
${parameter:+word} substitute value of word only if parameter is set
$ echo ${sv:+'substitute for sv'}
substitute for sv
${parameter:=word} assign parameter the value of word if parameter is unset
$ echo ${not_set:='now it IS set'}
now it IS set
$ echo "$not_set"
now it IS set
That line is setting the value of a variable called USER:
USER=....
The right side of the equal has several levels.
A "parameter expansion", the ${ }.
The parameter being expanded is $1. That's why it is ${1 ... }.
The value of $1 is being tested if it is NUL or unset, the ${1:- }.
If there is a value of $1 (other than nul), that value is substituted.
If $1 is NUL or unset, substitute the value at the rigth of the -.
The value between the - and the } is a "command substitution".
The "command execution" executes a command and replace its output.
The command is id -un. You can understand what it does with man id.
The command id -un prints a name. The current user if user is omitted.
The same command could be executed by $(id -un).
That would change the line to this:
$ USER=${1:-$(id -un)}
Which will set USER to the name given as positional parameter 1 or the name of the current user executing the line.
To try it, you can make a function:
$ tf(){ USER=${1:-$(id -un)}; echo "$USER"; }
If an value is given, that value is printed back:
$ tf bind
bind
If a user-name is not given, the executing user name is printed:
$ tf
bize
I would like to achieve this in Bash: echo $(a=1)and print the value of variable a
I test eval, $$a,{}, $() but none of them work as most of the times either I got literally a=1 or in one case (I don't remember which) it tried to execute the value.
I known that I can do: a=1;echo $a but because I'm little fun one command per line (even if sometimes is getting little complicated) I was wondering if is possible to do this either with echo or with printf
If you know that $a is previously unset, you can do this using the following syntax:
echo ${a:=1}
This, and other types of parameter expansion, are defined in the POSIX shell command language specification.
If you want to assign a numeric value, another option, which doesn't depend on the value previously being unset, would be to use an arithmetic expansion:
echo $(( a = 1 ))
This assigns the value and echoes the number that has been assigned.
It's worth mentioning that what you're trying to do cannot be done in a subshell by design because a child process cannot modify the environment of its parent.
>export FOOBAR=foobar; IFS=b echo ${FOOBAR}
I was expecting to see
foo ar
but I see
foobar
Why?
The IFS hasnt yet taken effect. add another ";":
FOOBAR=foobar IFS=b; echo ${FOOBAR}
In man bash section SIMPLE COMMAND EXPANSION
you can read (abbreviated):
When a simple command is executed
The words that the parser has marked as variable assignments (those preceding the command name) are saved for later processing.
The words that are not variable assignments or redirections are expanded.
...
The text after the = in each variable assignment ... [are] assigned to the variable.
so the IFS=b is done after expanding $FOOBAR.
[edit]I removed the technically incorrect answer.
http://tldp.org/LDP/abs/html/internalvariables.html
"This variable determines how Bash recognizes fields, or word boundaries, when it interprets character strings."
Here is a simple bash script:
a="asd"
b="qf"
echo "$a.$b"
echo "$a_$b"
It's output is:
asd.qf
qf
Why the second line is not "asd_qf" but "qf"?
Because you haven't defined a variable named a_. For that second printout to work, use:
echo "${a}_$b"
Your second echo displays the value of variable $a_ which is unset.
Use echo "${a}_$b"
The shell has rules about what can go in a variable name, and $a_ is interpreted as the variable named a_ (there is no variable with that name so its value is empty).
You can always add braces to be explicit. In this case, ${a}_$b will clearly identify what the variable name is and the result will be what you expect.