Using a variable containing spaces as a single argument - bash

Think you have a variable that contains a string of text with spaces inbetween and you want to use that as input arguments for another script. How would you go about passing the variable content without worrying about the space chars?
The following doesn't work:
VAR1=hello\ world
#... do something else
./a_script.sh $VAR1

Use double quotes:
VAR1=hello\ world
#... do something else
./a_script.sh "$VAR1"

Related

Contact multiple variable with string bash

This is my script code
#!/bin/bash
timestamp=$(date +%F-%T)
clinet_id="123"
STRING=s3://<bucketname>/folder/$client_id/$client_id_gdpr_access_report_$timestamp.csv
echo "$STRING"
$SHELL
If i run this code am getting timestamp value.csv file
how can i concatenate variable with string.
am expecting out put like below
s3://<bucketname>/folder/123/123_report_2022-01-25-14:55:47.csv
i can able to concatenateaccess_report_$timestamp.csv
if i add $client_id_ in the beginning, it will print
2022-01-25-14:55:47.csv
Expecting a better advice
You need to look better at the names of your variables; it's 'client_id' not 'clinet_id' ...
And you should take care of double quoting your string, and put braces around variables when in doubt:
STRING="s3://<bucketname>/folder/${client_id}/${client_id}_gdpr_access_report_${timestamp}.csv"

How to use custom variables in gitlab ci/cd?

I'm struggling with gitlab ci/cd variables. I see so many conflicting examples. Anyhow, what I would like to know is how to use variables outside and within scripts.
For example, in a job config, can I assign a variable in the script section with a bash command?
some-job:
variables:
SOME_VAR: ''
script:
- SOME_VAR = $(<file_with_a_line_of_text.txt)
In the above case, I'm not sure if I can do this. But I need to populate a variable with the file contents (i.e. artifact). Also, when do I use '$' in front of the variable? Some examples I see using these formats:
"SOME_VAR" #in quotes, no dollar sign
"${SOME_VAR}" #in quotes, with dollar sign and wrapped with curly braces
${SOME_VAR} #no quotes, with dollar sign and wrapped with curly braces
$SOME_VAR #i.e. without the double quotes or curly braces
SOME_VAR #i.e. without the double quotes, dollar sign, and curly braces
So many variations of usage that I can see in examples but don't really know when to use each style. And I can't find one example online of a custom variable being set in a script using a bash command.
When I'm setting variables in bash, I always do it without the spaces around the =:
VAR1="some string"
VAR2=23
VAR3=true
VAR4=$(cat /path/to/file.txt)
Let's go through these examples one at a time:
You can set a variable as a string by using quotes around the string.
You can set it to an int (probably a float too, but haven't personally used it)
You can set it to a bool
You can set it to the output of a command. The command is inside the command: $(#command).
Now let's use them:
echo $VAR1
# some string
echo "This is my variable $VAR1"
# This is my variable some string
echo "This is my variable ${VAR1}"
# This is my variable some string
echo ${VAR1}
# some string
echo "Error code ${VAR2}A"
# Error code 23A
echo "Error code $VAR2A"
# Error code --- Note: the variable $VAR2A dosn't exist
echo "Error code ${VAR2}${VAR1}"
# Error code 23some string
echo VAR1
# VAR1
echo "VAR1"
# VAR1
This illustrates the difference between the different forms, but in general, you reference a variable's value with $+variable-name. Doing "SOME_VAR" or SOME_VAR just prints out the string "SOME_VAR" (ie, not referencing a variable at all).
The difference between $SOME_VAR and ${SOME_VAR} is that the latter lets you use it when there is other content directly before or after the variable without erroring.
How to use custom variables in gitlab ci/cd?
Normally like in any other shell.
But note that gitlab-ci.yml is a yaml file and yaml has special parsings. Because of that in script: ex. - echo bla is the same as - 'echo bla', because in yaml the content of script: is an array of strings that are later spitted by shell.
how to use variables outside and within scripts.
Normally like in any other shell script.
when to use each style
"SOME_VAR" #in quotes, no dollar sign
SOME_VAR #i.e. without the double quotes, dollar sign, and curly braces
when you want to have a string SOME_VAR literally
"${SOME_VAR}"
is the same as "$SOME_VAR". When you want to have the content of SOME_VAR variable literally.
${SOME_VAR} #no quotes, with dollar sign and wrapped with curly braces
$SOME_VAR #i.e. without the double quotes or curly braces
When you want the content of SOME_VAR variable after word splitting and filename expansion. That means that SOME_VAR='*' and then echo "$SOME_VAR" will print *, but echo $SOME_VAR will print all files in current directory. You usually always want to quote expansions.
The form ${SOME_VAR} is used if concatenated with some other string, ex. $SOME_VARbla is not ${SOME_VAR}bla.
Do not use upper case variables in your scripts - prefer lower case. Prefer using upper case variables for exported variables. Be aware of clashes - COLUMN PATH USER UID are examples of already used variables.
can I assign a variable in the script section with a bash command?
Shell is space aware. var = val will execute a command named var with two arguments = and val. var=val will assign the string val to variable named var. Do:
- SOME_VAR=$(<file_with_a_line_of_text.txt)
In gitlab-ci I would prefer to use cat in case I will want to move to alpine. $(< is a bash extension.
- SOME_VAR=$(cat file_with_a_line_of_text.txt)
There doesn't seem to be any point in setting providing SOME_VAR in environment with variables: SOME_VAR.
When do I use '$' in front of the variable?
When you want to trigger variable expansion. Variable expansion substitutes variable name for the variable value.
Check your scripts with http://shellcheck.net . Read https://mywiki.wooledge.org/BashGuide a good shell introduction and https://wiki.bash-hackers.org/scripting/obsolete .

Defining and calling variables in shell script

I want to define variable in shell script as:
value1 = 40 (this can be number or character)
and want to use as in a text like:
$value1_position.xyz (I basically want 40_position.xyz)
How do I do this?
this should do:
${value1}_position.xyz
beware that the variable should be declared with this syntax
value1=40
notice the absence of spaces around the =
To define a variable, simply make sure there are no spaces between the variable name and value
value1=40
To use that variable in bash substitution, creating what you want, use the $ replacement symbol like so:
${value1}_position.xyz
To append that to your text file
echo "${value1}_position.xyz" >> file.txt

Theory: who can explain the use of =

can someone explain me with this code
data=$(date +"%Y-%m-%dS%H:%M:%S")
name="/home/cft/"$data"_test.tar"
touch $name
works, creating a new .tar file but this code doesn't work
data=$(date +"%Y-%m-%dS%H:%M:%S")
name= "/home/cft/"$data"_test.tar"
touch $name
and gives me this error: no such file or directory?
why the space between = and inverted commas creates this error?
Shell allows you to provide per-command environment overrides by prefixing the command with one or more variable assignments.
name= "/home/cft/"$data"_test.tar"
asks the shell to run the program named /home/cft/2013-10-08S12:00:00_test.tar (for example) with the value of name set to the empty string in its environment.
(In your case, the error occurs because the named tar file either doesn't exist or, if it does, is not an executable file.)
A variable assignment is identified by having no whitespace after the equal sign.
(name = whatever, of course, is simply a command called name with two string arguments, = and whatever.)
You can't have whitespace between the equal sign and the definition.
http://www.tldp.org/LDP/abs/html/varassignment.html
There is no theory behind this. It's just a decision the language designers made, and which the parser enforces.
In BASH (and other Bourne type shells like zsh and Kornshell), the equal sign cannot have spaces around it when setting variables.
Good:
$ foo="bar"
Bad:
$ foo= "bar"
$ foo = "bar"
There's no real reason that would prevent spaces from being used. Other programming languages have no problems with this. It's just the syntax of the shell itself.
The reason might be related to the original Bourne shell parsing where the shell would break up a command line based upon whitespace. That would make foo=bar a single parameter instead of two or three (depending if you have white space on both sides or just one side of the equal sign). The shell could see the = sign, and know this parameter is an assignment.
The shell parameter parsing is very primitive in many ways. Whitespace is very important. The shell has to be small and fast in order to be responsive. That means stripping down unessential things like complex line parsing.
Inverted commas I believe you mean quotation marks. Double quotes are used to override the breaking out of parameters over white space:
Bad:
$ foo=this is a test
bash: is: command not found
Good:
$ foo="this is a test"
Double quotes allow interpolation. Single quotes don't:
$ foo="bar"
$ echo "The value of foo is $foo"
The value of foo is bar
$ echo 'The value of foo is $foo'
The value of foo is $foo.
If you start out with single quotes, you can put double quotes inside. If you have single quotes, you can put double quotes inside.
$ foo="bar"
$ echo "The value of foo is '$foo'"
The value of foo is 'bar'
$ echo 'The value of foo is "$foo"'
The value of foo is "$foo"
This means you didn't have to unquote $data. However, you would have to put curly braces around it because underscores are legal characters in variable names. Thus, you want to make sure that the shell understand that the variable is $data and not $data_backup:
name="/home/cft/${data}_test.tar"

How does bash know where my variable names end?

Given:
myvar=Hello
echo $myvar -> Shows Hello (fine so far)
echo $myvar#world -> shows Hello#world (why? I thought it would complain that here is no such variable called myvar#world)
echo ${myvar#world} -> shows just Hello (again, why?)
The second case splits up into three parts:
[echo] [$myvar][#world]
1 2 3
Part 1 is the command, part 2 is a parameter, and part 3 is a string literal. The parameter stops on r since the # can't be part of the variable name (#'s are not allowed in variable names.)
The shell parser will recognise the start of a parameter name by the $, and the end by any character which cannot be part of the variable name. Normally only letters, numbers and underscores are allowed in a variable name, anything else will tell the shell that you're finished specifying the name of the variable.
All of these will print out $myvar followed by six literal characters:
echo $myvar world
echo $myvar?world
echo $myvar#world
If you want to put characters which can be part of a parameter directly after the parameter, you can include braces around the parameter name, like this:
myvar=hello
echo ${myvar}world
which prints out:
helloworld
Your third case is substring removal, except without a match. To get it to do something interesting, try this instead:
myvar="Hello World"
echo ${myvar#Hello }
which just prints World.
variables cannot contain a "#" so the shell knows its not part of a variable.
The construct ${myvar#world} actually is a string manipulator explained below:
# is actuially a string modifier that will remove the first part of the string matching "world". Since there is no string matching world in myvar is just echos back "hello"

Resources