105.1 Lesson 2
Certificate: |
LPIC-1 |
---|---|
Version: |
5.0 |
Topic: |
105 Shells and Shell Scripting |
Objective: |
105.1 Customize and use the shell environment |
Lesson: |
2 of 3 |
Introduction
Think of a variable as an imaginary box in which to temporarily place a piece of information. The same as with its initialization scripts, Bash classifies variables as either shell/local (those which live only within the limits of the shell in which they were created) or environment/global (those that are inherited by children shells and/or processes). In fact, in the previous lesson we had a look at shells and their configuration or initialization scripts. It is now convenient to point out that the power of these startup files lies in the fact that they allow us to use variables — as well as aliases and functions — which help us create and customize the shell environment of our choice.
Variables: Assignment and Reference
A variable can be defined as a name containing a value.
In Bash, giving a value to a name is called variable assignment and it is the way in which we create or set variables. On the other hand, the process of accessing the value contained in the name is called variable referencing.
The syntax for assigning variables is:
<variable_name>=<variable_value>
For example:
$ distro=zorinos
The variable distro
equals zorinos
, that is to say, there is a portion of memory holding the value zorinos
— with distro
being the pointer to it.
Note, however, that there can not be any space on either side of the equal sign when assigning a variable:
$ distro =zorinos -bash: distro: command not found $ distro= zorinos -bash: zorinos: command not found
Because of our mistake, Bash read distro
and zorinos
as commands.
To reference a variable (that is, to check its value) we use the echo
command preceding the variable name with a $
sign:
$ echo $distro zorinos
Variable Names
When choosing the name of variables, there are certain rules that we must take into consideration.
The name of a variable may contain letters (a-z
,A-Z
), numbers (0-9
) and underscores (_
):
$ distro=zorinos $ echo $distro zorinos $ DISTRO=zorinos $ echo $DISTRO zorinos $ distro_1=zorinos $ echo $distro_1 zorinos $ _distro=zorinos $ echo $_distro zorinos
It may not start with a number or Bash will get confused:
$ 1distro=zorinos -bash: 1distro=zorinos: command not found
It may not contain spaces (not even using quotes); by convention, underscores are used instead:
$ "my distro"=zorinos -bash: my: command not found $ my_distro=zorinos $ echo $my_distro zorinos
Variable Values
Concerning the reference or value of variables it is also important to consider a number of rules.
Variables may contain any alphanumerical characters (a-z
,A-Z
,0-9
) as well as most other characters (?
,!
,*
,.
,/
, etc.):
$ distro=zorin12.4? $ echo $distro zorin12.4?
Variable values must be enclosed in quotes if they contain single spaces:
$ distro=zorin 12.4 -bash: 12.4: command not found $ distro="zorin 12.4" $ echo $distro zorin 12.4 $ distro='zorin 12.4' $ echo $distro zorin 12.4
Variable values must also be enclosed in quotes if they contain such characters as those used for redirection (<
,>
) or the pipe symbol (|
). The only thing the following command does is create an empty file named zorin
:
$ distro=>zorin $ echo $distro $ ls zorin zorin
This works, though, when we use the quotes:
$ distro=">zorin" $ echo $distro >zorin
However, single and double quotes are not always interchangeable. Depending on what we are doing with a variable (assigning or referencing), the use of one or the other has implications and will yield different results. In the context of variable assignment single quotes take all the characters of the variable value literally, whereas double quotes allow for variable substitution:
$ lizard=uromastyx $ animal='My $lizard' $ echo $animal My $lizard $ animal="My $lizard" $ echo $animal My uromastyx
On the other hand, when referencing a variable whose value includes some initial (or extra) spaces — sometimes combined with asterisks — it is mandatory that we use double quotes after the echo
command to avoid field splitting and pathname expansion:
$ lizard=" genus | uromastyx" $ echo $lizard genus | uromastyx $ echo "$lizard" genus | uromastyx
If the reference of the variable contains a closing exclamation mark, this must be the last character in the string (as otherwise Bash will think we are referring to a history
event):
$ distro=zorin.?/!os -bash: !os: event not found $ distro=zorin.?/! $ echo $distro zorin.?/!
Any backslashes must be escaped with another backslash. Also, if a backslash is the last character in the string and we do not escape it Bash will interpret we want a line break and give us a new line:
$ distro=zorinos\ > $ distro=zorinos\\ $ echo $distro zorinos\
In the next two sections we will sum up the main differences between local and environment variables.
Local or Shell Variables
Local or shell variables exist only in the shell in which they are created. By convention, local variables are written in lower-case letters.
For the sake of carrying out a few tests, let us create a local variable. As explained above, we choose an appropriate variable name and equate it to an appropriate value. For instance:
$ reptile=tortoise
Let us now use the echo
command to reference our variable and check that everything went as expected:
$ echo $reptile tortoise
In certain scenarios — such as when writing scripts — immutability can be an interesting feature of variables. If we want our variables to be immutable, we can either create them readonly
:
$ readonly reptile=tortoise
Or turn them so after they have been created:
$ reptile=tortoise $ readonly reptile
Now, if we try to change the value of reptile
, Bash will refuse:
$ reptile=lizard -bash: distro: readonly variable
Note
|
To list all readonly variables in our current session, type |
A useful command when dealing with local variables is set
.
set
outputs all of the currently assigned shell variables and functions. Since that can be a lot of lines (try it yourself!), it is recommended to use it in combination with a pager such as less
:
$ set | less BASH=/bin/bash BASHOPTS=checkwinsize:cmdhist:complete_fullquote:expand_aliases:extglob:extquote:force_fignore:histappend:interactive_comments:login_shell:progcomp:promptvars:sourcepath BASH_ALIASES=() BASH_ARGC=() BASH_ARGV=() BASH_CMDS=() BASH_COMPLETION_COMPAT_DIR=/etc/bash_completion.d BASH_LINENO=() BASH_SOURCE=() BASH_VERSINFO=([0]="4" [1]="4" [2]="12" [3]="1" [4]="release" [5]="x86_64-pc-linux-gnu") BASH_VERSION='4.4.12(1)-release' (...)
Is our reptile
variable there?
$ set | grep reptile reptile=tortoise
Yes, there it is!
However, reptile
— being a local variable — will not be inherited by any child processes spawned from the current shell:
$ bash $ set | grep reptile $
And, of course, we cannot echo out its value either:
$ echo $reptile $
Note
|
By typing the |
To unset any variables (either local or global), we use the unset
command:
$ echo $reptile tortoise $ unset reptile $ echo $reptile $
Note
|
|
Global or Environment Variables
Global or environment variables exist for the current shell as well as for all subsequent processes spawned from it. By convention, environment variables are written in uppercase letters:
$ echo $SHELL /bin/bash
We can recursively pass the value of these variables to other variables and the value of the latter will ultimately expand to that of the former:
$ my_shell=$SHELL $ echo $my_shell /bin/bash $ your_shell=$my_shell $ echo $your_shell /bin/bash $ our_shell=$your_shell $ echo $our_shell /bin/bash
In order for a local shell variable to become an environment variable, the export
command must be used:
$ export reptile
With export reptile
we have turned our local variable into an environment variable so that child shells can recognize it and use it:
$ bash $ echo $reptile tortoise
Likewise, export
can be used to set and export a variable, all at once:
$ export amphibian=frog
Now we can open a new instance of Bash and successfully reference the new variable:
$ bash $ echo $amphibian frog
Note
|
With |
The export
command will also give us a list of all existing environment variables when typed on its own (or with the -p
option):
$ export declare -x HOME="/home/user2" declare -x LANG="en_GB.UTF-8" declare -x LOGNAME="user2" (...) declare -x PATH="/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games" declare -x PWD="/home/user2" declare -x SHELL="/bin/bash" declare -x SHLVL="1" declare -x SSH_CLIENT="192.168.1.10 49330 22" declare -x SSH_CONNECTION="192.168.1.10 49330 192.168.1.7 22" declare -x SSH_TTY="/dev/pts/0" declare -x TERM="xterm-256color" declare -x USER="user2" declare -x XDG_RUNTIME_DIR="/run/user/1001" declare -x XDG_SESSION_ID="8" declare -x reptile="tortoise"
Note
|
The command |
Two more commands that can be used to print a list of all environment variables are env
and printenv
:
$ env SSH_CONNECTION=192.168.1.10 48678 192.168.1.7 22 LANG=en_GB.UTF-8 XDG_SESSION_ID=3 USER=user2 PWD=/home/user2 HOME=/home/user2 SSH_CLIENT=192.168.1.10 48678 22 SSH_TTY=/dev/pts/0 MAIL=/var/mail/user2 TERM=xterm-256color SHELL=/bin/bash SHLVL=1 LOGNAME=user2 XDG_RUNTIME_DIR=/run/user/1001 PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games _=/usr/bin/env
On top of being a synonym for env
, we can sometimes use printenv
in a similar way as we use the echo
command to check for the value of a variable:
$ echo $PWD /home/user2 $ printenv PWD /home/user2
Note, however, that with printenv
the variable name is not preceded by $
.
Note
|
|
Running a Program in a Modified Environment
env
can be used to modify the shell environment at a program’s time of execution.
To start a new Bash session with as empty an environment as possible — clearing most variables (as well as functions and aliases) — we will use env
with the -i
option:
$ env -i bash
Now most of our environment variables are gone:
$ echo $USER $
And only a few remain:
$ env LS_COLORS= PWD=/home/user2 SHLVL=1 _=/usr/bin/printenv
We can also use env
to set a particular variable for a particular program.
In our previous lesson, when discussing non-interactive non-login shells, we saw how scripts do not read any standard startup files but instead they look for the value of the BASH_ENV
variable and use it as their startup file if it exists.
Let us demonstrate this process:
-
We create our own startup file called
.startup_script
with the following content:CROCODILIAN=caiman
-
We write a Bash script named
test_env.sh
with the following content:#!/bin/bash echo $CROCODILIAN
-
We set the executable bit for our
test_env.sh
script:$ chmod +x test_env.sh
-
Finally, we use
env
to setBASH_ENV
to.startup_script
fortest_env.sh
:$ env BASH_ENV=/home/user2/.startup_script ./test_env.sh caiman
The
env
command is implicit even if we get rid of it:$ BASH_ENV=/home/user2/.startup_script ./test_env.sh caiman
Note
|
If you do not understand the line |
Common Environment Variables
Time now for reviewing some of the most relevant environment variables that are set in Bash configuration files.
DISPLAY
-
Related to the X server, this variable’s value is normally made up of three elements:
-
The hostname (the absence of it means
localhost
) where the X server is running. -
A colon as a delimiter.
-
A number (it is normally
0
and refers to the computer’s display).$ printenv DISPLAY :0
An empty value for this variable means a server without an X Window System. An extra number — as in
my.xserver:0:1
— would refer to the screen number if more than one exists.
-
HISTCONTROL
-
This variable controls what commands get saved into the
HISTFILE
(see below). Their are three possible values:ignorespace
-
Commands starting with a space will not be saved.
ignoredups
-
A command which is the same as the previous one will not be saved.
ignoreboth
-
Commands which fall into any of the two previous categories will not be saved.
$ echo $HISTCONTROL ignoreboth
HISTSIZE
-
This sets the number of commands to be stored in memory while the shell session lasts.
$ echo $HISTSIZE 1000
HISTFILESIZE
-
This sets the number of commands to be saved in
HISTFILE
both at the start and at the end of the session:$ echo $HISTFILESIZE 2000
HISTFILE
-
The name of the file which stores all commands as they are typed. By default this file is located at
~/.bash_history
:$ echo $HISTFILE /home/user2/.bash_history
NoteTo view the contents of
HISTFILE
, we simply typehistory
. Alternatively, we can specify the number of commands we want to see by passing an argument (the number of the most recent commands) tohistory
as inhistory 3
. HOME
-
This variable stores the absolute path of the current user’s home directory and it is set when the user logs in.
This piece of code — from
~/.profile
— is self-explanatory (it sources"$HOME/.bashrc"
if it exists):# include .bashrc if it exists if [ -f "$HOME/.bashrc" ]; then . "$HOME/.bashrc" fi
NoteIf you do not quite understand the
if
statement, do not worry: just refer to the lessons about shell scripting.Remember that
~
is equivalent to$HOME
:$ echo ~; echo $HOME /home/carol /home/carol
NoteCommands can be concatenated with a semicolon (
;
).We can also prove this with an
if
statement:$ if [ ~ == "$HOME" ]; then echo "true"; else echo "false"; fi true
NoteRemember: The equals sign
=
is used for variable assignment.==
is used to test for equality. HOSTNAME
-
This variable stores the TCP/IP name of the host computer:
$ echo $HOSTNAME debian
HOSTTYPE
-
This stores the architecture of the host computer’s processor:
$ echo $HOSTTYPE x86_64
LANG
-
This variable saves the locale of the system:
$ echo $LANG en_UK.UTF-8
LD_LIBRARY_PATH
-
This variable consists of a colon-separated set of directories where shared libraries are shared by programs:
$ echo $LD_LIBRARY_PATH /usr/local/lib
MAIL
-
This variable stores the file in which Bash searches for email:
$ echo $MAIL /var/mail/carol
Another common value for this variable is
/var/spool/mail/$USER
. MAILCHECK
-
This variable stores a numeric value which indicates in seconds the frequency with which Bash checks for new mail:
$ echo $MAILCHECK 60
PATH
-
This environment variable stores the list of directories where Bash looks for executable files when told to run any program. In our example machine this variable is set through the system-wide
/etc/profile
file:if [ "`id -u`" -eq 0 ]; then PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" else PATH="/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games" fi export PATH
Through the
if
statement the identity of the user is tested and — depending on the result of the test (root
or otherwise) — we will obtain onePATH
or the other. Finally the chosenPATH
is propagated withexport
.Observe two things regarding the value of
PATH
:-
Directory names are written using absolute paths.
-
The colon is used as a delimiter.
If we wanted to include the folder
/usr/local/sbin
in thePATH
for regular users, we will modify the line so that it looks like this:(...) else PATH="/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games:/usr/local/sbin" fi export PATH
Now we can see how the value of the variable changes when we login as a regular user:
# su - carol $ echo $PATH /usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games:/usr/local/sbin
NoteWe could have also added
/usr/local/sbin
to the user’sPATH
at the command line by typing eitherPATH=/usr/local/sbin:$PATH
orPATH=$PATH:/usr/local/sbin
— the former making/usr/local/sbin
the first directory to be searched for executable files; the latter making it the last.
-
PS1
-
This variable stores the value of the Bash prompt. In the following chunk of code (also from
/etc/profile
), theif
statement tests for the identity of the user and gives them a very discrete prompt accordingly (#
forroot
or$
for regular users):if [ "`id -u`" -eq 0 ]; then PS1='# ' else PS1='$ ' fi
NoteThe
id
ofroot
is0
. Becomeroot
and test it yourself withid -u
.Other Prompt Variables include:
PS2
-
Normally set to
>
and used as a continuation prompt for long multiline commands. PS3
-
Used as the prompt for the
select
command. PS4
-
Normally set to
+
and used for debugging.
SHELL
-
This variable stores the absolute path of the current shell:
$ echo $SHELL /bin/bash
USER
-
This stores the name of the current user:
$ echo $USER carol
Guided Exercises
-
Observe the variable assignment under the “Command(s)” column and indicate if the resulting variable is “Local” or “Global”:
Command(s) Local Global debian=mother
ubuntu=deb-based
mint=ubuntu-based; export mint
export suse=rpm-based
zorin=ubuntu-based
-
Study the “Command” and the “Output” and explain the meaning:
Command Output Meaning echo $HISTCONTROL
ignoreboth
echo ~
/home/carol
echo $DISPLAY
reptilium:0:2
echo $MAILCHECK
60
echo $HISTFILE
/home/carol/.bash_history
-
Variables are being set incorrectly under the “Wrong Command” column. Provide the missing information under “Right Command” and “Variable Reference” so that we get the “Expected Output”:
Wrong Command Right Command Variable Reference Expected Output lizard =chameleon
chameleon
cool lizard=chameleon
chameleon
lizard=cha|me|leon
cha|me|leon
lizard=/** chameleon **/
/** chamelon **/
win_path=C:\path\to\dir\
C:\path\to\dir\
-
Consider the purpose and write the appropriate command:
Purpose Command Set the language of the current shell to Spanish UTF-8 (
es_ES.UTF-8
).Print the name of the current working directory.
Reference the environment variable which stores the information about
ssh
connections.Set
PATH
to include/home/carol/scripts
as the last directory to search for executables.Set the value of
my_path
toPATH
.Set the value of
my_path
to that ofPATH
. -
Create a local variable named
mammal
and assign it the valuegnu
: -
Using variable substitution, create another local variable named
var_sub
with the appropriate value so that when referenced viaecho $var_sub
we obtain:The value of mammal is gnu
: -
Turn
mammal
into an environment variable: -
Search for it with
set
andgrep
: -
Search for it with
env
andgrep
: -
Create, in two consecutive commands, an environment variable named
BIRD
whose value ispenguin
: -
Create, in a single command, an environment variable named
NEW_BIRD
whose value isyellow-eyed penguin
: -
Assuming you are
user2
, create a folder namedbin
in your home directory: -
Type the command to add the
~/bin
folder to yourPATH
so that it is the first directorybash
searches for binaries: -
To guarantee the value of
PATH
remains unaltered across reboots, what piece of code — in the form of anif
statement — would you put into~/.profile
?
Explorational Exercises
-
let
: more than arithmetic expression evaluation:-
Do a manpage or web search for
let
and its implications when setting variables and create a new local variable namedmy_val
whose value is10
— as a result of adding 5 and 5: -
Now create another variable named
your_val
whose value is5
— as a result of dividing the value ofmy_val
into 2:
-
-
The result of a command in a variable? Of course, that is possible; it is called command substitution. Investigate it and study the following function named
music_info
:music_info(){ latest_music=`ls -l1t ~/Music | head -n 6` echo -e "Your latest 5 music files:\n$latest_music" }
The result of the command
ls -l1t ~/Music | head -n 6
becomes the value of the variablelatest_music
. Then the variablelatest_music
is referenced in theecho
command (which outputs the total number of bytes occupied by theMusic
folder and the latest five music files stored in theMusic
folder — one per line).Which of the following is a valid synonym for
latest_music=`ls -l1t ~/Music | head -n 6`
Option A:
latest_music=$(ls -l1t ~/Music| head -n 6)
Option B:
latest_music="(ls -l1t ~/Music| head -n 6)"
Option C:
latest_music=((ls -l1t ~/Music| head -n 6))
Summary
In this lesson we learned:
-
Variables are a very important part of the shell environment as they are used by the shell itself as well as by other programs.
-
How to assign and reference variables.
-
The differences between local and global (or environment) variables.
-
How to make variables readonly.
-
How to turn a local variable into an environment variable with the
export
command. -
How to list all environment variables.
-
How to run a program in a modified environment.
-
How to make variables persistent with the help of startup scripts.
-
Some common environment variables:
DISPLAY
,HISTCONTROL
,HISTSIZE
,HISTFILESIZE
,HISTFILE
,HOME
,HOSTNAME
,HOSTTYPE
,LANG
,LD_LIBRARY_PATH
,MAIL
,MAILCHECK
,PATH
,PS1
(and other prompt variables),SHELL
andUSER
. -
The meaning of the tilde (
~
). -
The very basics of
if
statements.
Commands used in this lesson:
echo
-
Reference a variable.
ls
-
List directory contents.
readonly
-
Make variables immutable. List all readonly variables in current session.
set
-
List all variables and functions in current session.
grep
-
Print lines matching a pattern.
bash
-
Launch a new shell
unset
-
Unset variables.
export
-
Turn a local variable into an environment variable. List environment variables.
env
-
List environment variables. Run a program in a modified environment.
printenv
-
List environment variables. Reference a variable.
chmod
-
Change mode bits of a file, for example make it executable.
history
-
List previous commands.
su
-
Change user ID or become superuser.
id
-
Print user ID.
Answers to Guided Exercises
-
Observe the variable assignment under the “Command(s)” column and indicate if the resulting variable is “Local” or “Global”:
Command(s) Local Global debian=mother
Yes
No
ubuntu=deb-based
Yes
No
mint=ubuntu-based; export mint
No
Yes
export suse=rpm-based
No
Yes
zorin=ubuntu-based
Yes
No
-
Study the “Command” and the “Output” and explain the meaning:
Command Output Meaning echo $HISTCONTROL
ignoreboth
Both duplicate commands and those starting with a space will not be saved in
history
.echo ~
/home/carol
The
HOME
ofcarol
is/home/carol
.echo $DISPLAY
reptilium:0:2
reptilium
machine has a X server running and we are using the second screen of the display.echo $MAILCHECK
60
Mail will be checked every minute.
echo $HISTFILE
/home/carol/.bash_history
history
will be saved in/home/carol/.bash_history
. -
Variables are being set incorrectly under the “Wrong Command” column. Provide the missing information under “Right Command” and “Variable Reference” so that we get the “Expected Output”:
Wrong Command Right Command Variable Reference Expected Output lizard =chameleon
lizard=chameleon
echo $lizard
chameleon
cool lizard=chameleon
cool_lizard=chameleon
(for example)echo $cool_lizard
chameleon
lizard=cha|me|leon
lizard="cha|me|leon"
orlizard='cha|me|leon'
echo $lizard
cha|me|leon
lizard=/** chameleon **/
lizard="/** chameleon **/"
orlizard='/** chameleon **/'
echo "$lizard"
/** chamelon **/
win_path=C:\path\to\dir\
win_path=C:\\path\\to\\dir\\
echo $win_path
C:\path\to\dir\
-
Consider the purpose and write the appropriate command:
Purpose Command Set the language of the current shell to Spanish UTF-8 (
es_ES.UTF-8
).LANG=es_ES.UTF-8
Print the name of the current working directory
echo $PWD
orpwd
Reference the environment variable which stores the information about
ssh
connectionsecho $SSH_CONNECTION
Set
PATH
to include/home/carol/scripts
as the last directory to search for executables.PATH=$PATH:/home/carol/scripts
Set the value of
my_path
toPATH
.my_path=PATH
Set the value of
my_path
to that ofPATH
.my_path=$PATH
-
Create a local variable named
mammal
and assign it the valuegnu
:mammal=gnu
-
Using variable substitution, create another local variable named
var_sub
with the appropriate value so that when referenced viaecho $var_sub
we obtainThe value of mammal is gnu
:var_sub="The value of mammal is $mammal"
-
Turn
mammal
into an environment variable:export mammal
-
Search for it with
set
andgrep
:set | grep mammal
-
Search for it with
env
andgrep
:env | grep mammal
-
Create, in two consecutive commands, an environment variable named
BIRD
whose value ispenguin
:BIRD=penguin; export BIRD
-
Create, in a single command, an environment variable named
NEW_BIRD
whose value isyellow-eyed penguin
:export NEW_BIRD="yellow-eyed penguin"
or
export NEW_BIRD='yellow-eyed penguin'
-
Assuming you are
user2
, usemkdir
to create a folder namedbin
in your home directory:mkdir ~/bin
or
mkdir /home/user2/bin
or
mkdir $HOME/bin
-
Type the command to add the
~/bin
folder to yourPATH
so that it is the first directorybash
searches for binaries:PATH="$HOME/bin:$PATH"
PATH=~/bin:$PATH
orPATH=/home/user2/bin:$PATH
are equally valid. -
To guarantee the value of
PATH
remains unaltered across reboots, what piece of code — in the form of anif
statement — would you put into~/.profile
?if [ -d "$HOME/bin" ] ; then PATH="$HOME/bin:$PATH" fi
Answers to Explorational Exercises
-
let
: more than arithmetic expression evaluation:-
Do a manpage or web search for
let
and its implications when setting variables and create a new local variable namedmy_val
whose value is10
— as a result of adding 5 and 5:let "my_val = 5 + 5"
or
let 'my_val = 5 + 5'
-
Now create another variable named
your_val
whose value is5
— as a result of dividing the value ofmy_val
into 2:let "your_val = $my_val / 2"
or
let 'your_val = $my_val / 2'
-
-
The result of a command in a variable? Of course, that is possible; it is called command substitution. Investigate it and study the following function named
music_info
:music_info(){ latest_music=`ls -l1t ~/Music | head -n 6` echo -e "Your latest 5 music files:\n$latest_music" }
The result of the command
ls -l1t ~/Music | head -n 6
becomes the value of the variablelatest_music
. Then the variablelatest_music
is referenced in theecho
command (which outputs the total number of bytes occupied by theMusic
folder and the latest five music files stored in theMusic
folder — one per line).Which of the following is a valid synonym for
latest_music=`ls -l1t ~/Music | head -n 6`
It is option A:
latest_music=$(ls -l1t ~/Music| head -n 6)