cp -R "~/photo dir" /backups #method1
cp -R ~"/photo dir" /backups #method2
cp -R ~/"photo dir" /backups #method3
"~/"
to the user’s home directory and then append the quoted directory name that includes a space."~/"
to the user’s home directory and then append the quoted directory name that includes a space."~/"
to the user’s home directory and then append the quoted directory name that includes a space."$HOME/photo dir"
will be successful.$ ls -1
Beach photo1.jpg
Photo1.jpg
Photo2.jpg
Script.sh
$ cat script.sh
for i in $(ls *.jpg); do
mv $i ${i}.bak
done
( command )
sh command
{ command; }
(( command ))
reference. Subshells are one way for a programmer to capture (usually with the intent of processing) the output from a program or script. Commands to be run inside a subshell are enclosed inside single parentheses and preceeded by a dollar sign: DIRCONTENTS=$(ls -l) echo ${DIRCONTENTS}
echo "1 2 3" | awk '{for (i=1; i<=NF; i++) s=s+$i};END {print s}'
reference. AWK is a programming language that is designed for processing text-based data, either in files or data streams, or using shell pipes. In other words you can combine awk with shell scripts or directly use at a shell prompt.
find / -name "finance.db" 1>results.txt 2>/dev/null
reference. Syntax to redirect stderr (standard error) to a file: command 2> errors.txt
.
sed -i '/^$/d' textfile
sed '/^$/d' textfile
cat textfile | sed '/^$/d
sed -i 's/^$//' textfile
reference
sed : sed is a stream editor. A stream editor is used to perform basic text transformations on an input stream.
-i[SUFFIX] : This option specifies that files are to be edited in-place.
‘/^$/d’ : regex is between the //. ^ is the beginning of the line, $ is the end of the line. ^$ means the start and end have nothing in between.
d : Delete the pattern space; immediately start next cycle.
Warning, this example above will not work on a mac terminal due to different UNIX flavours. There is a way to make it work on a mac adding an extra flag -e
, or even just --
(found on StackOverflow): sed -i -e '/^$/d' textfile.txt
awk -F: '/user1/{print $1 "-" $3 "-" $6}' /etc/passwd
reference. Traditionally, the /etc/passwd file is used to keep track of every registered user that has access to a system. The /etc/passwd file is a colon-separated file that contains the following information: 1-Username
, 2-Password
, 3-User ID (UID)
, 4-Group ID (GID)
, 5-User ID Info (GECOS)
, 6-Home directory
, 7-Command/shell
"set -e"
in a Bash script?reference. The set -e option instructs bash to immediately exit if any command [1] has a non-zero exit status. You wouldn’t want to set this for your command-line shell, but in a script it’s massively helpful. In all widely used general-purpose programming languages, an unhandled runtime error - whether that’s a thrown exception in Java, or a segmentation fault in C, or a syntax error in Python - immediately halts execution of the program; subsequent lines are not executed.
mysql < file.sql > file.txt
Note: check the question below for a variant.
mysql < file.sql > out.txt
Note: check the question above for a variant.
reference. The Linux and Unix access rights flags setuid and setgid (short for set user identity and set group identity)[1] allow users to run an executable with the file system permissions of the executable’s owner or group respectively and to change behaviour in directories.
cat {$1,textfile}
cat textfile | awk [print $1]
cat textfile | awk '{print $1}'
awk textfile {print $1}
(reverse-i-search)`':
Note: On the Mac it will show bck-i-search:
instead of (reverse-i-search)
.
var=$( expr 10 / 8 )
(( var= 10 /8 ))
var=$(( 10 / 8 ))
var=$(echo 'scale=2; 10 / 8' | bc)
reference. The bc command is used for command line calculator. It is similar to basic calculator by using which we can do basic mathematical calculations. The division with 2 digit precision will be passed to bc
, evaluated, and assigned to the variable.
txt=Penguins
[[ $txt =~ [a-z]{8} ]]; echo $?
HAL>
SHELL="HAL\>"
SHELL="HAL>"
export PS1="HAL>"
PS1="HAL\>"
VAR="/var/www/html/website.com/html/"
echo "${VAR#*/html}"
/website.com/html/
/html/website.com/html/
/var/www/html/website.com/
reference
What is happening here quoting the POSIX shell specification: ${parameter#[word]}
. Remove Smallest Prefix Pattern. The word shall be expanded to produce a pattern. The parameter expansion shall then result in parameter, with the smallest portion of the prefix matched by the pattern deleted.
For instance ${VAR#?}
expands to the value of $VAR with the first character deleted. And ${VAR#\*/html}
expands to include all characters to and including the/html
text which will be deleted from the variable producing the output of/website.com/html/
#!/usr/bin/env bash
~/usr/bin/env bash
'$!/usr/bin/env bash
#/usr/bin/env bash
The date is: Sun Mar 24 12:30:06 CST 2019!
echo "The date is: !"
echo "The date is: date!"
echo "The date is: (date)!"
echo "The date is: $(date)!"
A. /home/demo.sh
B. ./demo.sh
C. ~/demo.sh
D. bash /home/demo.sh
E. bash demo.sh
find . -type html
find . -name *.html
find *.html
find . -name \*.html -print
The second seems well, but will expand the \* if there is any .html file on your working directory.
cat < in.txt > out.txt
(( $a == $b ))
echo $?
$a
and $b
.$a
and $b
are equal.$b
if it is larger than $a
.$a
if it is larger than $b
.; ;
: :
done
$$
#!/usr/bin/env bash
case $num in
1)
echo "one"
;;
2)
echo "two"
;;
*)
echo "a mystery"
;;
esac
touch file{1+10}.txt
touch file{1-10}.txt
touch file{1..10}.txt
touch file(1..10).txt
$$
$?
$!
$@
#!/bin/bash
fname=john
john=thomas
echo ${!fname}
A
B
C
D
Here’s a text based version of Q.30:
ll
-rw-r--r-- 1 frankmolev staff 374 Jun 3 19:30 .
-rw-r--r-- 1 frankmolev staff 1666 Jun 3 19:30 ..
-rw-r--r-- 1 frankmolev staff 0 Jun 3 19:30 file1.txt
-rw-r--r-- 1 frankmolev staff 0 Jun 3 19:30 file2.txt
..
ll | sed -e 's,file,text,g'
-rw-r--r-- 1 frankmolev staff 374 Jun 3 19:30 .
-rw-r--r-- 1 frankmolev staff 1666 Jun 3 19:30 ..
-rw-r--r-- 1 frankmolev staff 0 Jun 3 19:30 file1.file
-rw-r--r-- 1 frankmolev staff 0 Jun 3 19:30 file2.file
..
-rw-r--r-- 1 frankmolev staff 374 Jun 3 19:30 .
-rw-r--r-- 1 frankmolev staff 1666 Jun 3 19:30 ..
-rw-r--r-- 1 frankmolev staff 0 Jun 3 19:30 file1.txt
-rw-r--r-- 1 frankmolev staff 0 Jun 3 19:30 file2.txt
..
-rw-r--r-- 1 frankmolev staff 68 Jun 3 19:30 .
-rw-r--r-- 1 frankmolev staff 1666 Jun 3 19:30 ..
-rw-r--r-- 1 frankmolev staff 374 Jun 3 19:30 .
-rw-r--r-- 1 frankmolev staff 1666 Jun 3 19:30 ..
-rw-r--r-- 1 frankmolev staff 0 Jun 3 19:30 text1.txt
-rw-r--r-- 1 frankmolev staff 0 Jun 3 19:30 text.txt
..
#!/bin/bash
read -p "Enter your pet type." PET
if [ $PET = dog ] ;then
echo "You have a dog"
fi
history --shared
history --combined
shopt -s histappend
$@
treats each quoted argument as a separate entity. $*
treats the entire argument string as one entity.$*
treats each quoted argument as a separate entity. $@
treats the entire argument string as one entity.$*
is used to count the arguments passed to a script, $@
provides all arguments in one string.$*
is the wildcard that includes all arguments with word splitting, $@
holds the same data but in an array.if [ -f file.txt ]; then
echo "file.txt exists"
fi
/usr/bin/test
/usr/bin/[
the built-in [ command
/usr/bin/[[
#!/bin/bash
Linux=('Debian' 'Redhat' 'Ubuntu' 'Android' 'Fedora' 'Suse')
x=3
Linux=(${Linux[@]:0:$x} ${Linux[@]:$(($x + 1))})
echo "${Linux[@]}"
/etc/bash.conf
~/.profile
/etc/bashprofile
~/profile
$ ls -l
total 0
-rwx------+ 1 user1 user1 0 Oct 27 10:54 data.txt
+
at the end of the 10-digit permission string signifies there’s an access control list. This could possibly give user2 permissions not visible by ls -l
.ls -l
.+
at the end of the 10-digit permission string signifies there’s an extended attribute set. This could give user2 permissions to read, write, and execute data.txt.#!/bin/bash
declare -A ARRAY=([user1]=bob [user2]=ted [user3]=sally)
KEYS=(${!ARRAY[@]})
for (( i=0; $i < ${#ARRAY[@]}; i+=1 ));do
echo ${KEYS[$i]} - ${ARRAY[${KEYS[$i]}]}
done
ls Hello[[.vertical-line.]]World
Hello.vertical-line.World
Hello[[.vertical-line.]]World
Hello|World
ls nonexistentfile | grep "No such file" > out.txt
#!/bin/bash
read -p "Enter text " var
if [[ "$var" =~ "^[0-9]+$" ]];then
echo "Is numeric"
else
echo "Is not numeric"
fi
^[0-9]]+$
Only this will prove to be true and “Is numeric” would be printed on the screen due to incorrect syntax. By encapsulating the regular expression in double quotes every match will fail except the text string ^[0-9]+$
The regex must not be quoted to work properly.
history | find cp
history | grep cp
grep cp history
cp history
for i in $(ls); do ... done
for $(ls); do ... done
for i in $ls; do ... done
for $ls; do ... done
|
->
\#
@
#!/usr/bin/env bash
greeting="Hello"
echo $greeting, everybody!
(( num -gt 5 ))
[[$num -lt 5]]
(( num > 5 ))
num > 5
$ ls -l
apple
banana
bananapple
banapple
pineapple
strawberry
$ shopt -s extglob
$ ls -l @(ba*(na)|a+(p)le)
apple
banana
apple
banana
bananapple
banapple
pineapple
strawberry
apple
banana
bananappple
banapple
pineapple
apple
banana
bananapple
banapple
pineapple
ls -l
-rwx------+ 1 user1 u1 0 Oct 1 10:00 data.txt
cd -
cat > notes -
VAR="This old man came rolling"
echo "\${VAR//man/rolling}"
Shall we play a game? yes\no
echo "Shall we play a game? yes/\no"
echo "Shall we play a game\? yes\\no"
echo "Shall we play a game? yes\\no"
echo "Shall we play a game? yes\no"
archive.tar
image1.gif
image1.jpg
image2.gif
image2.jpg
textfile1.txt
textfile2.txt
----------
`shopt -s extglob
rm !(*gif|*jpg)`
archive.tar
image1.gif
image1.jpg
image2.gif
image2.jpg
textfile1.txt
textfile2.txt
archive.tar
textfile1.txt
textfile2.txt
c : All of this files will be deleted
d:
image1.gif
image1.jpg
image2.gif
image2.jpg
#!/bin/bash
var="8"
if [ $var > 5 ]; then
echo "$var is greater than 5"
fi
w
A constant is a variable that is a rock that isn’t variable
var="A constant is a variable that is a variable that isn't variable"
echo "$var" | sed _____
s/\(.*\)variable\(.*variable\)/\1rock\2/'
s/variable/rock/'
s/variable/rock/g'
s/(.*\)variable\(.*variable\)/\1rock\2/'
echo 'Hello, $(whoami)!'
tar -ssh user@192.158.1.1 /bin/newfile
tar cvzf - /wwwdata | ssh root@192.168.1.201 "dd of=/backup/wwwdata.tar.gz"
scp -r directory user@192.168.1.1:/tmp
ls -lah
to the shortcut command lh
, what command should you use?alias lh='ls -lah'
link lh='ls -lah'
alias 'ls -lah'=lh
lh | ls -lah
$ ls -l
file10.txt
file1.txt
fileabc.txt
filea.txt
fileb.txt
filec.txt
$ ls -l file[^abc]*.txt
file1.txt
file10.txt
file10.txt
file1.txt
fileabc.txt
filea.txt
fileb.txt
filec.txt
fileabc.txt filea.txt fileb.txt filec.txt
filea.txt
fileb.txt
filec.txt
Reference
The caret (
^) symbol here negates matches inside the bracket.
cat <<EOF
------------------------
This is line 1.
This is line 2.
This is line 3.
------------------------
EOF
This is line 1.
This is line 2.
This is line 3.
------------------------This is line 1.This is line 2.This is line 3.------------------------
------------------------
This is line 1.
This is line 2.
This is line 3.
------------------------
------------------------
This is line 1.
This is line 2.
This is line 3.
------------------------
#!/bin/bash
echo 123446789 > out.txt
exec 3<> out.txt
read -n 4 <&3
echo -n 5 >&3
exec 3>&-
#!/bin/bash
shopt -s extglob
VAR=' This is... a string of characters '
VAR=${VAR##+([[:space:]])}; VAR=${VAR%%+([[:space:]])};
echo "$VAR"
<pre> This is... a string of characters</pre>
<pre> This is...a string of characters</pre>
<pre>This is... a string of characters</pre>
<pre>This is...a string of characters</pre>
References:
echo $((4/3))
cat > notes -
sed -E -n '/^(.)(.)\3\2\1$/p'
sed -E -n '/^(.)(.)(.).\2\1$/p'
sed -E -n '/^(.)(.)(.)\2\1$/p'
sed -E -n '/^(.)(.)(.)(.)\3\2\1$/p'
[[$A==$B]]
[[$A -eq $B]]
VAR="united states"
echo "${VAR^}"
#!/bin/bash
#condition 1
if [ $foo = "bar" ]; then echo "foo is bar"
fi
#condition 2
if [[ $foo = "bar" ]]; then echo "foo is bar"
fi
Explanation: The script as written outputs line 3: [: =: unary operator expected
. Define variable and assign value foo="bar"
, and both conditions will succeed.
$#
$@
0
$!
$ID
$@
$#
$$
A shebang line is required to execute a shell script.
‘bash script.sh’.
‘exec script.sh’.
ExecuteExecute permissions are required to execute a shell script.
cat -n animals | sort -r | head -n 5
1 Ant
2 Bear
3 Cat
4 Dog
5 Elephant
9 Ibex
B Hippo
7 Giraffe
6 Fox
5 Elephant
4 Dog
3 Cat
2 Bear
1 Ant10 Jaguar
Jaguar
Ibex
Hippo
Giraffe
Fox
9 Ibex
8 Hippo
7 Giraffe
6 Fox
5 Elephant
$HOME
my_var
1var
!
Which of the following one-liner Bash commands accomplishes this task?
find . -name "*.txt" -exec wc -l {} \; | awk '{total += $1} END {print total}'
grep -r ".*\.txt$" | wc -l
find . -type f -name "*.txt" | xargs wc -l | tail -n 1
find . -name "*.txt" -exec cat {} \; | wc -l
> overwrites the contents of the target file, while >> appends to the end of the target file.
> redirects input, while >> redirects output.
> is used for standard output, while >> is used for standard error.
> is a unary operator, while >> is a binary operator.