This is really for me, to remember stuff. Based upon Brian Holt's FrontendMasters course:
echo
prints stuff i.e. echo hi
--help
flag prints everything about the program i.e. ls --help
which ls
prints folder where the ls program is stored
!!
(bangbang) runs the previous command. i.e. pwd and ls -lsah and then you can do !! && ls -lsah
history
prints command history
.bash_history
file can be found in ~/ (home directory) but for some reason I cannot see it either. Edit: I didn't see it because it was first session. Subsequent sessions show it because commands in a session are stored in the file after session closes.
tail ~/.bash_history
SHORTCUTS source: Brian Holt course on FMs
CTRL + A – takes you to the beginning of the line
CTRL + E – takes you to the end of the line
CTRL + K – "yank" everything after the cursor
CTRL + U – "yank" everything before the cursor
CTRL + Y - "paste" (paste in quotes because it doesn't actually go into your system clipboard) everything you yanked
CTRL + L - clear the screen
CTRL + R – reverse search through history
SIGNALS
CTRL + C
- SIGINT(errupt)
CTRL + D
- SIGQUIT
VIM
:w
save
:q
quit
or :wq
if you want to quit with unsaved changes: :q!
(aka the hell outta here)
:help tutor
(didn't work for me) or (vim adventures](https://vim-adventures.com/) to learn
FILES
less textfile.txt
vim like read only view
man ls
shows manual
ls --help
abbreviated manual
cat textfile.txt
like less but without scrolling
tail textfile.txt
last 10 lines
mkdir -p my/name/is/brian
creates all the nested directories
touch
creates new file
rm
removes file
rm -r directory_name
removes directory if not empty
cp {{filename}} {{filename}}
> copies file
mv {{filename}} {{filename}}
> renames files
WILDCARDS
rm *.txt
is the same as rm file1.txt file2.txt etc
ls file*.txt
* replaces anything: 1, 10, etc
ls file?.txt
? replaces one char
ls file[1-3].txt
lists file1, file2 and file3
ls file[a-c].txt
lists filea, fileb and filec
EXPANSIONS
touch file{1..4}.txt
creates file1, file2, file3 and file4
touch file{a..z}.txt
same
touch {Aisha,Lanie,Joumana,Krista}-profile.txt
echo {a..z} # prints a to z
echo {z..a} # reverse order
echo {0..100..2} # prints every other (aka even) number from 0 to 100
echo {100..0..5} # prints every 5th number in reverse order from 100 to 0
echo {a..z}{1..5} # prints out a1 a2 a3 a4 a5 b1 b2 b3 <etc>
STREAMS
stdout
stdout means redirecting the output of a program to another file. like: ls 1> whatever-file.txt
. if u do 1>>
it will add it to existing content
stderr
2>
and 2>>
both stdout and stderr
>
like cat no-file.txt > error-log.txt
stdin
<
take the content of a file and puts it in stdin so another program can use it
stdout and stdin
grep info < file.txt 1> new-file.txt
for instance..
pipes (use output of one program for another one. previous one refers to files.)
ls -lsah | grep info
output of one program is used for the next one
USERS
whoami
cat /etc/passwd
principle of least power
useradd brian
only superuser can do
sudo su
change into superuser. sudo = superuser do. switches to root user (terrible idea). u can get out with "exit"
^ su can add users, so can run useradd {{name}}
CTRL + D to exit root user (sensible apprach)
userdel brian
To change into a user you type: su {{name of user}}
sudo useradd brian
sudo passwd brian
# make a password, I made something simple like "asdf"
su brian
# your new password
whoami
sudo su
# brian is not in the sudoers file. This incident will be reported.
^ new user can't sudo. We fix it with groups:
sudo usermod -aG sudo brian
to add brian to the list of users that can sudo. -a === append. -G === groups`
d rwx rwx rwx
-->
d / - directory or file
file permission for user that owns the file, for the group that owns the file, for everyone not in the group.
r = read, w = write, x = execute
chown
change ownership
whoami # should say ubuntu
cd /
mkdir hello # permission denied, you don't have permission to do that here
sudo mkdir hello # works, but now hello is owned by root:root
ls -l # notice hello is owned by root:root
touch hello/text.txt # permission denied, you don't own hello
sudo chown ubuntu:ubuntu hello # it's <group>:<user>
ls -l # notice hello is now owned by ubuntu:ubuntu
touch hello/text.txt # works!
chmod
changes mod
whoami # should be ubuntu still
cd ~ # go to home directory
sudo touch secret.txt # make a file as root
ls -l secret.txt # -rw-r--r-- so root can read and write but no one else can
echo "very secret message" >> secret.txt # doesn't work, permission denied
sudo chmod u=rw,g=rw,o=rw secret.txt # make it so anyone can read or write to the file
echo "very secret message" >> secret.txt # works this time!
cat secret.txt # should see very secret message
or sudo chmod 666 secret.txt
^
chmod +x secret.txt
makes a file executable
chmod -x secret.txt
removes the executable from a file
ENVIRONMENTS
printenv
< prints env variables
echo $USER
USER=brian
< for that particular session
sudo vi /etc/environment
< u can save new env variables. u need to quit the terminal. any user will have it
vi ~/.bashrc
> write export NAME_VARIABLE=bla bla bla
> and then source ~./.bashrc
mdifference between .bashrc and .bash_profile? former runs at start of each session. latter runs only first time log in. profile should never be used
PROCESSES
ps
< processes run by user only. PID
means process id.
ps aux
< aux means all users. that is the difference with ps
.
ps aux | grep "ps"
< will find what I am looking for
kill -9 1783
< kills process 1783 (or kill -SIGKILL 1783
)
sleep 10 &
< means wait 10 seconds (sleep 10) and run on the background (&)
background / foreground >> i.e sleep 10
(foreground) / sleep 10 &
(background, because of &
)
ctrl z
will stop it
jobs
< show jobs and status
bg 1
(or whatever the id from jobs) < resumes in the background ie. sleep 1000 &
. jobs will show sleep -1000 running
fg 1
will resume it in the foreground
Processes ::>
if program run succesfully echo $?
will return 0. If not, it will return something other than 0 (1, 2, 130, etc). Chaining commands like the following will only work if the previous program finished w 0: touch status.txt && date >> status.txt >> uptime >> status.txt
(>> means append with a line break at the end)
touch status.txt || echo lol
means that 2nd command will only run if first didn't finish succesfully
true ; false ; echo hi
will run the 3 programs no matter what
SUBCOMMANDS
echo I think $(whoami) is very cool
echo the current date is $(date)
echo $(date +%r) - $(uptime) >> log.txt
The +%x
part is just saying what date of format you want, and I got that from reading date --help
echo $(cat < log.txt) user
echo
whoami hi
bacticks is the very old way of doing things
will add the output of whoami in the middle
SSH
sudo useradd -s /bin/bash -m -g ubuntu brian
-s /bin/bash
will run the bash for this user
-m
creates home folder for you
-g
ubuntu gives same permissions as group ubuntu
brian
is the name of the user
sudo passwd brian
it changes brian's password
su brian
changes user to brian
linking 2 machines with ssh
target machine + machine we will connect from
in primary: ssh-keygen -t rsa
generates public and private key. rsa is the flavor of key to be generated. can skip passphrase for now and add default location. creates .ssh folder w id_rsa and id_rsa.pub
in secondary: mkdir ~/.ssh
we cd into and we type vi authorized_keys
and we paste the cat id_rsa.pub
key into that
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
in secondary
ifconfig
will print bunch of stuff, like ip. we grab the inet ip address
in primary: ssh brian@ip-address
click yes
exit
to exit console of secondary and retunrn to primary
SFTP
sftp brian@ip-address
pwd
lpwd
is local pwd
lls
is local ls
put status.txt
copies file from primary to secondary server
runing script with ! means on the primary
!echo lol >> status.txt
!cat status.txt
put file-to-put.txt yay-new-file.txt
means file gets copied with new name
u can do ls
in secondary computer and you will see the file
get
will download files into my primary machine
WGET
wget -> copy paste of the internet
wget add_name_file
CURL
curl name_of_file
will print content in screen
curl name_of_file > game.sh
will add content into file
run python server on ubuntu
curl http://192.168.64.2:8000
will hit the server and print the response
curl http://182.168.64.2:8000 > res.txt
will stdout response into the file
curl -o res2.txt http://...
does the same
curl -O http://.../output.txt
will write in same file
^ GET
curl -X POST(or any other verb PUT, etc) http://...
curl -d "this is the body" http://...
it is a post because get doesnt have body
curl -X POST (or PUT orvwhatever) -d "request body" http://...
send cookies curl -b "name=brian" -X PATCH http://...
follow redirect curl -L http://...
otherwise dorent follow redirect
headers curl -H "accept-language: en-US" -H "Authorization: Bearer 12345" http://...
add -H for every header that is needed
copy request from browser dev tools : right click on network request, "copy as curl"
PACKAGE MANAGEMENT
sudo apt install aptitude
>> is a nice frontend to manage packages
apt-get
is the old one
apt
is the new one
apt install lolcat
wont work bc u dont have permissions
u need to do sudo apt install lolcat
sudo apt install nodejs
apt search nodejs
apt show nodejs
sudo apt autoremove
sudo apt update
< gets a new list from apt. doesnt upgrade any package
apt list
lists all the packages installed
apt list -upgreadable
sudo apt upgrade
< upgrades the packages or one in particular if u do sudo apt upgrade nodejs
(for example)
sudo apt full-upgrade
snap package manager
SCRIPTS
vi gen_files.sh
in vim: i
(insert mode)
mkdir -p ~/temp
cd ~/temp
touch file{1...10}.txt
echo done
to run the file:
source gen_files.sh
< changes the directory into /temp
. gen_files.sh
< change directory. works in more linux distros than source
bash gen_files.sh
< doesnt change directory
#!
to interpret the file
file w script can be without extension and first line will be #! /bin/bash
then we chmod +x gen_files
./gen_files
it will run
example with node. I need location of node : which node
will return /snap/bin/node
vi node_test
`
! /snap/bin/node
console.log('running from node')
`
chmod +x node_test
./node_test
echo $PATH
will output all the folder paths were programs are located
I need to run ./gen_files
because gen_files alone won't work. for it to work i need to add it to the path. how?
mkdir my_bin
mv gen_files /my_bin
vi .bashrc
at the end we write export PATH=~/my_bin:$PATH
we restart console
we need full path that is why we add ~
and the :
allows to attach current path $PATH at the end
echo $PATH will now include /my_bin
path and u can run gen_files
without anything else
VARIABLES IN SCRIPTS
vi gen_files
DESTINATION=~/temp
u can add "" or not its optional if it had spaces you would have to
then u can write mkdir -p $DESTINATION
cd $DESTINATION
vars font have to be capital case
FILE_PREFIX=file
touch ${FILE_PREFIX}{1..10}.txt curly
braces needed because ambiguous
USER INPUT
DESTINATION=$1
means the first argument provided. $0
is the invocation of the script. and then u continue to use the var DESTINATION
. or u can use $1
all across the file. or $2
for second argument, etc
for the prompt to user to type sth to be used:
read -p "enter a file prefix: " FILE_PREFIX
the var name is used in the script. -p
is prompt
`
! /bin/bash
DESTINATION=~/temp
read -p "enter a file prefix: " FILE_PREFIX
mkdir -p $DESTINATION
cd ~/temp
touch ${FILE_PREFIX}{1..10}.txt
echo done
`
CONDITIONALS
if [ -z $DESTINATION ]; then
echo "no path provided, defaulting to ~/temp"
DESTINATION=~/temp
fi
fi
is how if statements end. is if backwards.
-z
is testing if length of $DESTINATION is zero
test 15 -eq 15 && echo is true
test brian = brian && echo is true
test 15 -gt 14 && echo is true
-lt
-ge
-le
less than or equal
-test -e ~/output.txt && echo is true
-e
tests if file exists
--w
tests if file exists and I can write with the current user
check man test
for all conditionals
CASE / ELSE IF
touch greater-than
chmod +x greater-than
vi greater-than
`#! /bin/bash
if [ $1 -gt 10 ]; then
echo "greater than ten"
elif [ $1 -lt 10]; then
echo "less than 10"
else
"equals 10"
fi
`
another one:
`
! /bin/bash
case $1 in
"smile")
echo ":)"
;;
"sad")
echo ":("
;;
"laugh")
echo ":D"
;;
*)
echo "I don't know that one yet"
;;
esac
`
esac
is case backwards...
*)
means everything else
ARRAYS
`
! /bin/bash
friends=(Kyle Marc Jem "Brian Holt" Sarah)
echo My second friend is ${friends[1]}
for friend in ${friends[*]}
do
echo friend: $friend
done
echo "I have ${#friends[*]} friends"
`
WHILE
`
! /bin/bash
let "NUM_TO_GUESS = ${RANDOM} % 10 + 1"
NUM_TO_GUESS=$(( $RANDOM % 10 + 1 ))
GUESSED_NUM=0
echo "guess a number between 1 and 10"
while [ $NUM_TO_GUESS -ne $GUESSED_NUM ]
do
read -p "your guess: " GUESSED_NUM
done
echo "you got it!"
`
-ne
means not equal
-p
stops execution until user inputs. assigns input to variable
JOBS / CRON
in ubuntu there are cron folders in /etc/ >> cron_daily, cron_hourly, etc. if the script is executable (chmod +x bla bla) and inside that folder it will run. as long as computer is on, of course.
$() in a script runs a sub-script or program inside.
what if I want to run the job (script) every minute? enter crontab!
crontab -e will ask which editor: nano, vim, etc
choose vi number 2
- * * * * /home/ubuntu/my_bin/make_new_file
stars check crontab guru website... (@daily, @reboot too) the other is the path to the script (needs to be executable!) it runs the scripts as your user and u can add a root user if needed: sudo crontab -u root -e
CUSTOMIZE SHELL
echo $PS1
PS1="whatever"
and whatever will b the prompt :)
read course notes for cooler customisations
how to do colors in echo: echo -e "this is color \e[32mgreen"
the \e[32m
will transform the word into green. useful for scripts wher u need to show pass, test, etc
awesomebash in github for really cool stuff