Bash Special Characters
Edit me

Bash Special Characters

=====

# Comments

comments can be occurred following the end of a command and even embedded with a pipe.

$ echo "test" |\
# delete `e` from it
ed -e 's/e//g'
tst

; semicolon

Command separator. It will permits putting two or more commands on the same line.

;; / ;;& / :&

Terminators of case option. ;;& / :& are compatible with verison 4+.

. dot

Equivalent to source, which is a bash built-in cmd.

, comma

links together a series of arithmetic operations. All are evaluated, but only the last one is returned.

$ let "b=((a=9, 15 / 3))"; echo $a $b
9 5

concatenate strings.

$ ls /{,tmp}
/:
bin  boot  dev  etc  export  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

/tmp:
bash_test.sh  dido  matrix  pid  set  test  test_pipe  test.sh

convert to lowercase

$ name="MATRIX"; echo ${name,}; echo ${name,,}
mATRIX
matrix

\ backslash

Escape

``` backquote

command substitution

$ for i in  `ls -1`; do echo $i; done
bash_test.sh
dido
matrix
pid
set
test
test_pipe
test.sh

: colon

null command. It will always return true and equivalent as NO-OP(do-nothing operation)

$ ls -1 | grep colon; echo $?
1

$ ls -1 | grep colon; :;  echo $?
0

Provide a placeholder where a binary operation is expected.

$ n=1; $((n = $n + 1)); echo $n
-bash: 2: command not found
2

$ n=1; : $((n = $n + 1)); echo $n
2

Provide a placeholder where a command is expected.

$ n=1; if [ $n -eq 2 ]; then : ; else echo $n; fi
1

Used in parameter substitution / Variable expansion / substring replacement. combination with the redirection operators with >, truncates a file to zero length, without changing its permissions. If the file did not previously exist, creates it. with >>, has no effect on a pre-existing target file. If the file did not previously exist, creates it. NOTE: applies to regular files, not pipes, symlinks, and certain special files.

! exclamation

reverse

$ ! true; echo $?
1

$ true; echo $?
0

* asterisk

wild card for filename expansion or arithmetic operator

$ echo *
bash_test.sh dido matrix pid set test test_pipe test.sh 

? question

test operator in format condition?result-if-true:result-if-false

$ n=1; (( m = n==1?2:3 )) ; echo $m
2

$’…’

Quoted string expansion

$ echo $'\ttest'
        test

$ echo $'aa\x27'
aa'

() parentheses

List of commands within () starts a subshell

$ echo $BASH_SUBSHELL; (echo $BASH_SUBSHELL)
0
1

{a,b,c} brace

brace expansion

$ echo \"{These,words,are,quoted}\"
"These" "words" "are" "quoted"

{} curly brackets

anonymous function. unlike in a “standard” function, the variables inside it remain visible outside

$ { a=123; } ; echo $a
123

The code block enclosed in braces may have I/O redirected to and from it.

$ { echo a; echo b; } > /tmp/test ; cat /tmp/test
a
b

(())

interger expansion

$ a=$(( 2*2 )) ; echo $a
4

> / &> / >> / < / <>

redirection &> redirect both stdout and stderr to file << redirect used in a here document which is a special-purpose code block. It uses a form of I/O redirection to feed a command list to an interactive program or a command, such as ftp, cat, etc.

$ cat ./test.sh
#!/bin/bash

sftp localhost <<EOF
cd /tmp
ls -1
quit
EOF

$ ./test.sh
Warning: Permanently added 'localhost' (ECDSA) to the list of known hosts.
Connected to localhost.
sftp> cd /tmp
sftp> ls -1
dido
matrix
subshell.sh
test
test.sh
test_pipe
sftp> quit

<<< redirect used in a here string which can be considered as a stripped-down form of a here document.

$ grep -q test <<< "This is a test string"; echo $?
0

same as

$ echo "This is a test string" | grep -q test ; echo $?
0

(command)> / <(command) process substitution

>| force overwrite

$ bash -C echo > test.sh
bash: test.sh: cannot overwrite existing file

$ ls -al test.sh; bash -C echo >| test.sh; ls -al test.sh
-rwxr-xr-x 1 jun_zou jun_zou 5 Aug 16 19:48 test.sh
/usr/bin/echo: /usr/bin/echo: cannot execute binary file
-rwxr-xr-x 1 jun_zou jun_zou 0 Aug 16 19:48 test.sh

- redirect from/to stdin or stdout

$ cat -
test
test

$ echo matrix | cat -
matrix

Redirect stdin

Transfer files to remote host with - redirect

$ ls -al /tmp/visual; tar cf - visual | ssh -q localhost 'tar xf - -C /tmp'; ls -al /tmp/visual
ls: cannot access /tmp/visual: No such file or directory
-rw-rw-r-- 1 jun_zou jun_zou 2845 Jul 28  2022 /tmp/visual

~+ current working directory

~- previous working directory

$ echo ~+; cd ~-; echo ~+ ; cd ~-; echo ~+
/tmp/test
/home/jun_zou
/tmp/test

$* / $@

The positional parameters starting from the first.
With doublequotes ", both are same. If without, $* will take all as a single word. $@ will take each parameter as a quoted string, that is, the parameters are passed on intact, without interpretation or expansion.

$ cat <<EOF> ./bash_special_characers.sh
#!/bin/bash

function print_all_parameters() {
  echo "There are $# parameters here: "
  i=1
  while [ ${i} -le $# ]
  do
    echo "$i parameter: ${!i}"
    : $((++i))
  done
  echo ""
}

echo "Unquoted \$*"
print_all_parameters $*

echo "Quoted \"\$*\""
print_all_parameters "$*"

echo "Unquoted \$@"
print_all_parameters $@

echo "Quoted \"\$@\""
print_all_parameters "$@"
EOF

$ ./bash_special_characers.sh 12 34
Unquoted $*
There are 2 parameters here:
1 parameter: 12
2 parameter: 34

Quoted $*
There are 1 parameters here:
1 parameter: 12 34

Unquoted $@
There are 2 parameters here:
1 parameter: 12
2 parameter: 34

Quoted $@
There are 2 parameters here:
1 parameter: 12
2 parameter: 34

When working with doublequotes ", all parameters in $* will put the first character of IFS between the elements in order to construct the final output string. But $& will not do in this way.

$ cat bash_special_parmeters.sh
#! /bin/bash

# bash_special_parmeters.sh - Cmd args - positional parameter demo

#### Set the IFS to | ####
IFS='|'

echo "Command-Line Arguments Demo"

echo "*** All args displayed using \$@ positional parameter ***"
echo "$@"        #*** double quote added ***#

echo "*** All args displayed using \$* positional parameter ***"
echo "$*"        #*** double quote added ***#

$ ./bash_special_parmeters.sh apple pear grape lemon
Command-Line Arguments Demo
*** All args displayed using $@ positional parameter ***
apple pear grape lemon
*** All args displayed using $* positional parameter ***
apple|pear|grape|lemon

$# hash mark

Number of positional parameters (decimal)

$ cat ./bash_special_parmeters.sh
#!/bin/bash

echo "$#"

$ ./bash_special_parmeters.sh  12 34
2

$?

Status of the most recently executed foreground-pipeline (exit/return code)

$- dash

Current option flags set by the shell itself.

$ cat bash_special_parmeters.sh
#!/bin/bash

echo "$-"

set -euo pipefail

echo "$-"

$ ./bash_special_parmeters.sh 12 34
hB
ehuB

$$

The process ID (PID) of the shell. In an explicit subshell it expands to the PID of the current “main shell”, not the subshell. This is different from $BASHPID!

$ echo $$; echo $BASHPID ; ( cd /usr; pstree -p | grep $$; echo "$$" )
33969
33969
           |             |-bash(33969)---bash(33868)-+-grep(33870)
33969

$ echo $$; echo $BASHPID ; ( cd /usr; pstree -p | grep $$; echo "$BASHPID" )
33969
33969
           |             |-bash(33969)---bash(34977)-+-grep(34979)
34977

$! exclamation mark

The process ID (PID) of the most recently executed background pipeline

$ ping -c 1000 localhost > /dev/null  &
[1] 47589

$ echo $!
47589

$0 zero

The name of the shell or the shell script (filename).

$ echo $0
-bash

$ cat bash_special_parmeters.sh
#!/bin/bash

echo "$0"

$ ./bash_special_parmeters.sh
./bash_special_parmeters.sh

$_ underscore

A kind of catch-all parameter. Directly after shell invocation, it’s set to the filename used to invoke Bash, or the absolute or relative path to the script, just like $0 would show it. Subsequently, expands to the last argument to the previous command.

$ cat bash_special_parmeters.sh
#! /bin/bash

echo "$_"

$ ./bash_special_parmeters.sh
./bash_special_parmeters.sh

$ cat bash_special_parmeters.sh
#! /bin/bash

echo test

echo "$_"

$ ./bash_special_parmeters.sh
test
test

More about bash special parameters and shell vaviables

Tags: bash