bash (Bourne Again Shell) II - 2018
Linux - system, cmds & shell
- Linux Tips - links, vmstats, rsync
- Linux Tips 2 - ctrl a, curl r, tail -f, umask
- Linux - bash I
- Linux - bash II
- Linux - Uncompressing 7z file
- Linux - sed I (substitution: sed 's///', sed -i)
- Linux - sed II (file spacing, numbering, text conversion and substitution)
- Linux - sed III (selective printing of certain lines, selective definition of certain lines)
- Linux - 7 File types : Regular, Directory, Block file, Character device file, Pipe file, Symbolic link file, and Socket file
- Linux shell programming - introduction
- Linux shell programming - variables and functions (readonly, unset, and functions)
- Linux shell programming - special shell variables
- Linux shell programming : arrays - three different ways of declaring arrays & looping with $*/$@
- Linux shell programming : operations on array
- Linux shell programming : variables & commands substitution
- Linux shell programming : metacharacters & quotes
- Linux shell programming : input/output redirection & here document
- Linux shell programming : loop control - for, while, break, and break n
- Linux shell programming : string
- Linux shell programming : for-loop
- Linux shell programming : if/elif/else/fi
- Linux shell programming : Test
- Managing User Account - useradd, usermod, and userdel
- Linux Secure Shell (SSH) I : key generation, private key and public key
- Linux Secure Shell (SSH) II : ssh-agent & scp
- Linux Secure Shell (SSH) III : SSH Tunnel as Proxy - Dynamic Port Forwarding (SOCKS Proxy)
- Linux Secure Shell (SSH) IV : Local port forwarding (outgoing ssh tunnel)
- Linux Secure Shell (SSH) V : Reverse SSH Tunnel (remote port forwarding / incoming ssh tunnel) /)
- Linux Processes and Signals
- Linux Drivers 1
- tcpdump
- Linux Debugging using gdb
- Embedded Systems Programming I - Introduction
- Embedded Systems Programming II - gcc ARM Toolchain and Simple Code on Ubuntu/Fedora
- LXC (Linux Container) Install and Run
- Linux IPTables
- Hadoop - 1. Setting up on Ubuntu for Single-Node Cluster
- Hadoop - 2. Runing on Ubuntu for Single-Node Cluster
- ownCloud 7 install
- Ubuntu 14.04 guest on Mac OSX host using VirtualBox I
- Ubuntu 14.04 guest on Mac OSX host using VirtualBox II
- Windows 8 guest on Mac OSX host using VirtualBox I
- Ubuntu Package Management System (apt-get vs dpkg)
- RPM Packaging
- How to Make a Self-Signed SSL Certificate
- Linux Q & A
- DevOps / Sys Admin questions
We need to get the permission to run a shell script (t.sh) using a command chmod u+x file_name:
$ cat t.sh #!/bin/bash # This is a testing script echo "Who are you?" who echo echo "System into: " uname -a $ t.sh bash: t.sh: command not found... $ ls -la total 12 drwxrwxr-x. 2 khong khong 4096 Aug 23 20:17 . drwx------. 21 khong khong 4096 Aug 23 20:13 .. -rw-rw-r--. 1 khong khong 54 Aug 23 20:17 t.sh $ chmod u+x t.sh $ ./t.sh Who are you? khong :0 2015-08-23 14:33 (:0) khong pts/0 2015-08-23 14:40 (:0) System into: Linux localhost.localdomain 3.6.10-4.fc18.x86_64 #1 SMP Tue Dec 11 18:01:27 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux
We put a special characters on the first line of a shell script to tell the OS which shell to use for our script file execution. Because the OS checks the initial characters of a program before attempting to execute it using exec, these characters we put in saves potential unsuccessful run attempt.
#!/bin/bash
The #! is useful if we want to run our script in a different shell.
- ";"
This line executes x, y, and z one by one.
$ x; y; z - "NEWLINE"
A RETURN in the middle of a quoted string will become a part of the string in bash script. In other words, it is a valid line break. - "|"
A pipe is a separator.
$ x | y | z
This line consists of three separate tasks. In the first job, the shell redirects standard output of the task x to standard input of task y and redirects y's output to z's standard input. - "&"
A pipe is a separator.
$ x & y & z
This line consists of three separate tasks. The tasks x and y will run in background, but z task will run as a foreground job.
To assign a value to a variable, use the following syntax:
variable=value
No spaces before and after the "=" sign.
$ name=Tom $ echo name name $ echo $name Tom
The second line of the example above shows that name does not represent Ton. Instead the string name is echoes as name. The shell substitutes only when a variable has $ sign. The leading $ makes the shell recognize that $name is the name of a variable, substitutes the value of the variable, and passes that value to echo.
$ echo $name Tom $ echo "$name" Tom $ echo '$name' $name $ echo \$name $name
The single quote can block the substitution. The backslash(\) takes away the meaning of $.
Since the double quote("") does not prevent the shell from substitution, we may keep using it to assign a value to a variable. It's helpful when we have a value with spaces in it:
fullname="Tom Jynx" $ echo $fullname Tom Jynx $ fullname=Tom Jynx bash: Jynx: command not found...
When we execute a command with a variable as an argument, the shell replaces the name of the variable with the value of the variable and passes that value to the program being executed. If the value of the variable contains a special characters (* or ?), the shell may expand that variable.
$ ls t2.sh t.sh $ list=t* $ echo "$list" t* $ echo $list t2.sh t.sh
The double quote("") blocked the pathname expansion while unquoted case sees the expansion. So, the unquoted case expands t* and passes the two values to the list.
The braces insulate the variable name from adjacent characters. Braces are necessary when concatenating a variable value with a string. The first try of the example above, we got the (null) string because the shell evaluates an unset variable as an empty. So, in the second try, we use braces, and got the intended outcome.
$ PRE=pre $ PREFIX=$PREfix $ echo $PREFIX $ PREFIX=${PRE}fix $ echo $PREFIX prefix
The bash refers to the arguments on its command line by position, using the special variables $1, $2, $3, and so forth.The name of the command is held in $0.
The PS1 variable holds the prompt string that the shell uses to let us know that it is waiting for a command.
$ PS1="[\u@\h \w \!]$ " [khong@localhost ~ 188]$
The prompt displays:
[user@host directory event]$where the directory is the basename of the working directory and event is the event number of the current command.
If we're working on more than one system, it might be better displaying the system name:
$ hostname localhost.localdomain [khong@localhost ~/TestScript 192]$ PS1="[$(hostname)]$ " [localhost.localdomain]$
Note that we used the command substitution in $(hostname).
If we want to display the full directory of the working directory not just the basename of it:
$ PS1=[${LOGNAME}@$(hostname)]'$PWD$ ' [khong@localhost.localdomain]/home/khong$ pushd ~/TestScript ~ ~ [khong@localhost.localdomain]/home/khong/TestScript$
We can put the command into our .bashrc:
export PS1=[${LOGNAME}@$(hostname)]'$PWD$ '
How to automate SSH login with or without password?
In this example, target = 165.81.168.97, user = root, code to run = /path/to/code/code.py:
- Password needed:
ssh "root@165.81.168.97" python /path/to/code/code.py
- Password NOT needed:
a. On a host machine
cd ~/.ssh ssh-copy-id -i id_rsa.pub 165.81.168.97
b. Still on the host machine, run the following:ssh "165.81.168.97" python /path/to/code/code.py
-
note: if there is no key, then we need to do the following:
ssh-keygen -t rsa -N ""
Linux - system, cmds & shell
- Linux Tips - links, vmstats, rsync
- Linux Tips 2 - ctrl a, curl r, tail -f, umask
- Linux - bash I
- Linux - bash II
- Linux - Uncompressing 7z file
- Linux - sed I (substitution: sed 's///', sed -i)
- Linux - sed II (file spacing, numbering, text conversion and substitution)
- Linux - sed III (selective printing of certain lines, selective definition of certain lines)
- Linux - 7 File types : Regular, Directory, Block file, Character device file, Pipe file, Symbolic link file, and Socket file
- Linux shell programming - introduction
- Linux shell programming - variables and functions (readonly, unset, and functions)
- Linux shell programming - special shell variables
- Linux shell programming : arrays - three different ways of declaring arrays & looping with $*/$@
- Linux shell programming : operations on array
- Linux shell programming : variables & commands substitution
- Linux shell programming : metacharacters & quotes
- Linux shell programming : input/output redirection & here document
- Linux shell programming : loop control - for, while, break, and break n
- Linux shell programming : string
- Linux shell programming : for-loop
- Linux shell programming : if/elif/else/fi
- Linux shell programming : Test
- Managing User Account - useradd, usermod, and userdel
- Linux Secure Shell (SSH) I : key generation, private key and public key
- Linux Secure Shell (SSH) II : ssh-agent & scp
- Linux Secure Shell (SSH) III : SSH Tunnel as Proxy - Dynamic Port Forwarding (SOCKS Proxy)
- Linux Secure Shell (SSH) IV : Local port forwarding (outgoing ssh tunnel)
- Linux Secure Shell (SSH) V : Reverse SSH Tunnel (remote port forwarding / incoming ssh tunnel) /)
- Linux Processes and Signals
- Linux Drivers 1
- tcpdump
- Linux Debugging using gdb
- Embedded Systems Programming I - Introduction
- Embedded Systems Programming II - gcc ARM Toolchain and Simple Code on Ubuntu/Fedora
- LXC (Linux Container) Install and Run
- Linux IPTables
- Hadoop - 1. Setting up on Ubuntu for Single-Node Cluster
- Hadoop - 2. Runing on Ubuntu for Single-Node Cluster
- ownCloud 7 install
- Ubuntu 14.04 guest on Mac OSX host using VirtualBox I
- Ubuntu 14.04 guest on Mac OSX host using VirtualBox II
- Windows 8 guest on Mac OSX host using VirtualBox I
- Ubuntu Package Management System (apt-get vs dpkg)
- RPM Packaging
- How to Make a Self-Signed SSL Certificate
- Linux Q & A
- DevOps / Sys Admin questions
Ph.D. / Golden Gate Ave, San Francisco / Seoul National Univ / Carnegie Mellon / UC Berkeley / DevOps / Deep Learning / Visualization