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)