I/O in Linux¶
Global variables and initialization files¶
- Customizing the working environment has usually the following goals:
- minimize the routine operations to ease the overall work
- customize the working environment to best suite the user's needs
- Working environment in Linux can be customized with
- initialization files,
- variables configured in these files and
- with global variables
- Usually when Linux program is started it reads
- configured variables and global variables
- initialization files found from user's home directory (usually hidden files starting with . character)
- Initialization files in user's home directory include user specific environment settings and commands which can be utilized by running programs
- Below is an example where user's home directory content is listed
testuser@ubuntu-PC:~$ ls -a
. .bash_history .cache .local .sudo_as_admin_successful
.. .bash_logout data .profile .wget-hsts
backup.tar .bashrc .gnupg sqlit
- There are two types of variables in Linux:
- Local variables
- Global variables
- Local variables can be referred only from active shell
- Global variable values can be inherited to also to child processes
- Global variable cannot be returned to normal variable
- Variable name cannot start with a number
- Important: All global variables are also local variables, but not all local variables are global variables!
- Local or global variable values can be printed with echo command like in the example below
testuser@ubuntu-PC:~$ echo $MYVAR
100
- Variable names are always case-sensitive and are started with $ character
- Variable value can be set like in the following way:
testuser@ubuntu-PC:~$ myvar=200
testuser@ubuntu-PC:~$ echo $myvar
200
- Local variables are loaded to user's working environment with export command
- Below is an example of export command usage
- Example: Let's create MYVAR variable and set it's value to 100. This variable will then be added to global variables. Global variables are then printed with env command
testuser@ubuntu-PC:~$ MYVAR=100
testuser@ubuntu-PC:~$ export MYVAR
testuser@ubuntu-PC:~$ env
SSH_CONNECTION=10.0.2.2 49172 10.0.2.4 22
LESSCLOSE=/usr/bin/lesspipe %s %s
LANG=en_US.UTF-8
XDG_SESSION_ID=3
USER=testuser
MYVAR=100
PWD=/home/testuser
HOME=/home/testuser
SSH_CLIENT=10.0.2.2 49172 22
XDG_DATA_DIRS=/usr/local/share:/usr/share:/var/lib/snapd/desktop
SSH_TTY=/dev/pts/0
MAIL=/var/mail/testuser
TERM=xterm
SHELL=/bin/bash
SHLVL=1
LOGNAME=testuser
XDG_RUNTIME_DIR=/run/user/1000
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/usr/local/bin
LESSOPEN=| /usr/bin/lesspipe %s
_=/usr/bin/env
- Below are some examples of variable use
testuser@ubuntu-PC:~$ Firstname=James
testuser@ubuntu-PC:~$ Lastname=Tester
testuser@ubuntu-PC:~$ Fullname="${Firstname}, ${Lastname}"
testuser@ubuntu-PC:~$ echo $Fullname
James, Tester
testuser@ubuntu-PC:~$ Wizard="$Linus $(whoami) $Fullname"
testuser@ubuntu-PC:~$ echo Wizard
Wizard
testuser@ubuntu-PC:~$ echo $Wizard
testuser James, Tester
testuser@ubuntu-PC:~$ Linus="Username and fullname: "
testuser@ubuntu-PC:~$ echo $Wizard
testuser James, Tester
testuser@ubuntu-PC:~$ Wizard="$Linus $(whoami) $Fullname"
testuser@ubuntu-PC:~$ echo $Wizard
Fullname and username: testuser James, Tester
testuser@ubuntu-PC:~$
- Some variable names are reserved and should not be used
- Below is a table presenting variable names reserved for Bourne shell (Bash has also its own list of reserved variables)
Variable name | Definition |
---|---|
CDPATH | A colon-separated list of directories used as a search path for the cd built-in command. |
HOME | The current user's home directory; the default for the cd built-in. The value of this variable is also used by tilde expansion. |
IFS | A list of characters that separate fields; used when the shell splits words as part of expansion. |
If this parameter is set to a file name and the MAILPATH variable is not set, Bash informs the user of the arrival of mail in the specified file. | |
MAILPATH | A colon-separated list of file names which the shell periodically checks for new mail. |
OPTARG | The value of the last option argument processed by the getopts built-in. |
OPTIND | The index of the last option argument processed by the getopts built-in. |
PATH | A colon-separated list of directories in which the shell looks for commands. |
PS1 | The primary prompt string. The default value is "'\s-\v\$ '". |
PS2 | The secondary prompt string. The default value is "'> '". |
- Below is an example where the look of command prompt is customized with bash internal variable PS1
testuser@ubuntu-PC:~$ echo $PS1
\[\e]0;\u@\h: \w\a\]${debian_chroot:+($debian_chroot)}\u@\h:\w\$
- The following list can be used to describe the parameters used in the example above
Parameter | Description |
---|---|
\t or \T | Time (24h or 12h) |
\d | Date |
\w | Working directory |
\h | Computer name (host) |
\u | User name |
\$ | User prompt (# or $) |
-
It is recommended to save the prompt customization command in one of the initialization files, for example
- .bashrc in user's home directory
- /etc/bash.bashrc when command should be used system wide
-
Below is an example where prompt is edited and then returned back to original setting
- Store the original prompt on a variable (PS_TEMP)
- Change the prompt
- Return the original from variable (PS_TEMP)
testuser@ubuntu-PC:~$ PS_TEMP=$PS1
testuser@ubuntu-PC:~$ PS1="\h $(pwd) \$ "
ubuntu-PC /home/testuser $
ubuntu-PC /home/testuser $ PS1=$PS_TEMP
testuser@ubuntu-PC:~$
Initialization files¶
- Global variables should be stored in initialization/configuration files so user does not have make the changes again in each new session
- Usually programs have program specific initialization files created during the installation of the program
- These initialization files are usually the hidden files or directories starting with . character in user's home directory
- Examples of initialization files:
- .bashrc .vimrc .conkyrc .config/ .vim/
-
The most essential initialization files are the following:
- /etc/profile
- Includes system specific settings for all shells, which are common for all users: global variables (PATH, HOSTNAME, etc.) and other settings
- .profile
- User specific settings for all shells, for example LANG, PATH, program specific settings etc.
- This file is stored in each user's home directory
- File is read when shell is started during user's login process
- /etc/bash.bashrc
- Similar to /etc/profile, but includes settings only for bash shell
- .bashrc
- User specific settings for bash shell
- This file is stored in each user's home directory
- File is read every time shell is started (without login prompt) and always before any command is executed
- /etc/profile
-
Changes for initialization files are active after the next login or start of the shell
- Changes can also be activated immediately with source command:
testuser@ubuntu-PC:~$ source /etc/profile
testuser@ubuntu-PC:~$ source /etc/bash.bashrc
testuser@ubuntu-PC:~$ source $HOME/.profile
testuser@ubuntu-PC:~$ source $HOME/.bashrc
Alias (Command shortcut)¶
- Alias can be and is recommended to set for long commands used frequently
- alias command can be used to print all defined aliases
testuser@ubuntu-PC:~$ alias
alias alert='notify-send --urgency=low -i "$([ $? = 0 ] && echo terminal || echo error)" "$(history|tail -n1|sed -e '\''s/^\s*[0-9]\+\s*//;s/[;&|]\s*alert$//'\'')"'
alias egrep='egrep --color=auto'
alias fgrep='fgrep --color=auto'
alias grep='grep --color=auto'
alias l='ls -CF'
alias la='ls -A'
alias ll='ls -alF'
alias ls='ls --color=auto'
- A new alias can be set with the following command
testuser@ubuntu-PC:~$ alias md=mkdir
testuser@ubuntu-PC:~$ alias mdp=’mkdir -p’
- Important: When creating permanent aliases alias configuration should be included in either /etc/bash.bashrc or .bashrc file
- Example of using alias command
testuser@ubuntu-PC:~$ alias md=mkdir
testuser@ubuntu-PC:~$ ls
backup.tar data sqlit
testuser@ubuntu-PC:~$ md alias-test
testuser@ubuntu-PC:~$ ls
alias-test backup.tar data sqlit
- Below is another example where alias configuration is stored in .bashrc file
testuser@ubuntu-PC:~$ echo "alias md='mkdir’" >> ~/.bashrc
testuser@ubuntu-PC:~$ echo "alias n='netstat -an | grep LISTEN | less'" >> ~/.bashrc
testuser@ubuntu-PC:~$ source ~/.bashrc
testuser@ubuntu-PC:~$ n
tcp 0 0 127.0.0.53:53 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN
tcp6 0 0 :::22 :::* LISTEN
unix 2 [ ACC ] SEQPACKET LISTENING 12867 /run/udev/control
unix 2 [ ACC ] STREAM LISTENING 23756 /run/user/1000/systemd/private
unix 2 [ ACC ] STREAM LISTENING 23760 /run/user/1000/gnupg/S.dirmngr
unix 2 [ ACC ] STREAM LISTENING 23761 /run/user/1000/gnupg/S.gpg-agent
unix 2 [ ACC ] STREAM LISTENING 23762 /run/user/1000/gnupg/S.gpg-agent.extra
unix 2 [ ACC ] STREAM LISTENING 23763 /run/user/1000/gnupg/S.gpg-agent.ssh
unix 2 [ ACC ] STREAM LISTENING 23764 /run/user/1000/gnupg/S.gpg-agent.browser
I/O channels (input, output)¶
- There are three input/output channels in Unux process:
- stdin: input channel where data is transferred to the process, usually through a keyboard attached to the computer
- stdout: output channel for the process, which is dedicated usually for monitor attached to the computer by default
- stderr: error channel for the process, which is dedicated for monitor attached to the computer by default
- All three I/O channels are pointing monitor or pseudoterminal by default
-
User may redirect the channels to point to a file like in the examples below
-
Example 1. Print to the file
command > file.txt
- Example 2. Print to the end of the file
command >> file.txt
- Example 3. Print stdout and stderr to the file
command >& file.txt
- Example 4. Read from the file
command < file.txt
- Below are some examples of I/O channel usage
testuser@ubuntu-PC:~$ ls
alias-test
testuser@ubuntu-PC:~$ w > monitoring.txt
testuser@ubuntu-PC:~$ ls
alias-test monitoring.txt
testuser@ubuntu-PC:~$ cat monitoring.txt
06:39:29 up 1:50, 2 users, load average: 0.00, 0.00, 0.00
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
testuser tty1 - 05:05 1:34m 0.09s 0.03s -bash
testuser pts/0 10.0.2.2 05:05 0.00s 0.62s 0.00s w
testuser@ubuntu-PC:~$ ls
alias-test monitorointi.txt
testuser@ubuntu-PC:~$ cd..
cd..: command not found
testuser@ubuntu-PC:~$ cd.. >& error.txt
testuser@ubuntu-PC:~$ ls
alias-test monitoring.txt error.txt
testuser@ubuntu-PC:~$ cat error.txt
cd..: command not found
Command chaining¶
- Commands can be chained in the terminal, so that it is possible to execute multiple commands at the same time
- This way the commands are run in order (from left to right) and their execution is determined by the use of logical operators
- To chain commands, the following operators may be used:
- ; → the command following this operator is run regardless of whether the preceding command has been succesfully executed
- AND → the command following this operator is only executed if the preceding command is succesfully executed
- OR → the command following this operator is only executed if the preceding command has failed
-
The logical operators are typed in the following way:
- AND:
- logical operator AND (&&)
- OR:
- logical operator OR (||)
- AND:
-
Below are some examples of using command chaining
- Example 1: Print the current date, logged in user and computer's name with single line
testuser@ubuntu-PC:~$ date && whoami && hostname
ThuSep26 10:33:06 UTC 2019
testuser
ubuntu
- Example 2: Set variable and print the content of the variable to the screen
testuser@ubuntu-PC:~$ var="Date is $(date) and user is $(whoami)" ; echo $var
Date is Thu Sep26 10:38:54 UTC 2019 and user is testuser
- Example 3: Try to create a directory called newdata under the /etc directory and inform user whether the command was executed successfully
testuser@ubuntu-PC:~$ mkdir /etc/newdata && echo "Directory was created" || echo "Failed"
mkdir: cannot create directory "/etc/data": Permission denied
Failed
testuser@ubuntu:~$ sudo su
[sudo] password for testuser:
root@ubuntu-PC:~# mkdir /etc/data && echo "Directory was created" || echo "Failed"
Directory was created
Pipeline¶
- In Unix-based operating systems pipe command can be used to redirect standard output for another command for example
- Pipeline can be used with | character
- Several pipelines can be run in a row
- Standard output can be done in the beginning and at the end of the pipeline
- The syntax of pipeline is the following:
command1 | command2
- In this syntax example output from command1 (stdout) will be redirected as an input for command2 (stdin)
- Both commands will be executed in two separate processes and the execution will be done simultaneously
-
Below are a list of different examples presenting the use of the pipeline
-
Example 1: Count logged in users (both local and remote)
- w prints users (option -h without title information)
- wc counts the rows from the input, which then equals the amount of logged in users
testuser@ubuntu-PC:~$ w -h | wc -l
2
- Example 2: Print the content of /etc directory using less command
testuser@ubuntu-PC:~$ ls -la /etc | less
- Example 3: Sort the user list, add row numbers and print output to the file called users.txt
testuser@ubuntu-PC:~$ w –h | sort | cat -b > users.txt
- Example 4: Use cowsay program to print the current logged in user (program is installed first)
testuser@ubuntu-PC:~$ sudo apt install cowsay
testuser@ubuntu-PC:~$ cowsay Hello
_______
< Hello >
-------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
testuser@ubuntu-PC:~$ whoami | cowsay
__________
< testuser >
----------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
- Example 5: Use cowsay program to print the computer's name using luke-koala
testuser@ubuntu-PC:~$ cowsay -l
Cow files in /usr/share/cowsay/cows:
apt bud-frogs bunny calvin cheese cock cower daemon default dragon
dragon-and-cow duck elephant elephant-in-snake eyes flaming-sheep
ghostbusters gnu hellokitty kiss koala kosh luke-koala mech-and-cow
milkmoofasa moose pony pony-smaller ren sheep skeleton snowman stegosaurus
stimpy suse three-eyes turkey turtle tux unipony unipony-smaller vader
vader-koala www
testuser@ubuntu-PC:~$ echo $HOSTNAME | cowsay -f luke-koala
___________
< ubuntu-PC >
-----------
\
\ .
___ //
{~._.~}//
( Y )K/
()~*~()
(_)-(_)
Luke
Skywalker
koala