DEV Community

Pere Sola
Pere Sola

Posted on • Updated on


LINUX and command line stuff

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


CTRL + C - SIGINT(errupt)


: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]( to learn


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
rmremoves file
rm -r directory_name removes directory if not empty
cp {{filename}} {{filename}} > copies file
mv {{filename}} {{filename}} > renames files


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


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>
Enter fullscreen mode Exit fullscreen mode



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


2> and 2>>

both stdout and stderr

> like cat no-file.txt > error-log.txt


< 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


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
sudo su
# brian is not in the sudoers file.  This incident will be reported.
Enter fullscreen mode Exit fullscreen mode

^ 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


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


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


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


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

in secondary: mkdir ~/.ssh we cd into and we type vi authorized_keys and we paste the cat key into that

chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys

in secondary


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 brian@ip-address

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 -> copy paste of the internet
wget add_name_file


curl name_of_file will print content in screen
curl name_of_file > will add content into file

run python server on ubuntu

curl will hit the server and print the response
curl > 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


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"


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



in vim: i (insert mode)
mkdir -p ~/temp
cd ~/temp
touch file{1...10}.txt
echo done

to run the file:

source < changes the directory into /temp
. < change directory. works in more linux distros than source
bash < 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

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

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


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
vars font have to be capital case

touch ${FILE_PREFIX}{1..10}.txt curly braces needed because ambiguous


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


read -p "enter a file prefix: " FILE_PREFIX

cd ~/temp
touch ${FILE_PREFIX}{1..10}.txt
echo done


if [ -z $DESTINATION ]; then
echo "no path provided, defaulting to ~/temp"

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
-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


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"
"equals 10"

another one:


! /bin/bash

case $1 in
echo ":)"
echo ":("
echo ":D"
echo "I don't know that one yet"

esac is case backwards...

*) means everything else



! /bin/bash

friends=(Kyle Marc Jem "Brian Holt" Sarah)

echo My second friend is ${friends[1]}

for friend in ${friends[*]}
echo friend: $friend

echo "I have ${#friends[*]} friends"



! /bin/bash

let "NUM_TO_GUESS = ${RANDOM} % 10 + 1"

NUM_TO_GUESS=$(( $RANDOM % 10 + 1 ))

echo "guess a number between 1 and 10"

while [ $NUM_TO_GUESS -ne $GUESSED_NUM ]
read -p "your guess: " GUESSED_NUM

echo "you got it!"

-ne means not equal
-p stops execution until user inputs. assigns input to variable


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


echo $PS1

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

Top comments (0)

One Million Strong

We are an active and inclusive community of over one million registered creators, developers, and tech enthusiasts. Join us.