oneline functions
make a function which returns every input to first three characters
truncate() { echo "${1:0:3}"; }
the commands inside the braces need to be finish by semicolon if the closing brace is on the same line or in a script
truncate() {
echo "${1:0:3}"
}
sort: sort csv files easily
To sort text files including comma delimited (csv) files.
-t,
sets delimiter to a comma, if left empty, uses space as a delimiter-kN,M
from Nth-column to M-th column. if,M
is ommitted uses N and all columns after N for sortingf
flag to sort alaphabetically while ignoring case (otherwise all capitals preced all the lowercase in sorting)n
flag to sort numericallyr
flag reverses sorting (from biggest to lowest)-t$'\t'
to set tab as a seprator
sort example
sort -t, -k1,1f -k3,3nr <file>
Sorts a commma delimited file by first and third column alphabetically and numerically in descending order (respectively)
sort and keep the header unsorted
{ head -n1 file.csv; tail -n +2 file.csv | sort -t, -k1,1 ; } > sorted_file.csv
read: read a file line by line and do something with it
Read a file and reverse all lines
while IFS= read -r line; do
echo "$line" | rev
done < filename.txt
-r
flag ignores \
as escape characters
IFS=
prevents whitespace to be trimmed from front and back also
-a
flag will enable reading into an array which starts with an index of zero
heredocs: write line from command line
cat <<EOF > terminal-file.txt
# here write what you want on multiple lines
# finish by typing EOF
# In case you want to use a different signal instead of EOF use a different word
# cat <<END > terminal-file.txt will be ended by END
sed
How sed operates
sed
operates on individual lines of the input
- reads first line - puts into a pattern space
- excutes commands
- prints what is in pattern to output
- clears the pattern space
- reads next line
So if you supply no commands to sed sed '' file
it just outputs the content of the file.
It is the same as running cat file
The -n switch prevents default printing
There is an important switch -n
going ahead of the commands.
When -n
flag is present it negates the action of a 3rd step: negates content of pattern space to output.
Example
sed -n '' file`
runs and prints nothing
Telling the sed
what to do with which lines
The ’ ’ structure is used to define range of lines on which to operate specific commands.
The general structure is: sed 'ranges commands'
.
More commands can be included inside the ’ ’ to run consequtively when seprated by semicolon: sed 'ranges commands1; commands2'
Ranges
Ranges are defined by line numbers or pattern matching
Example
'1,2' first two lines
'1,+N' first line plus N more lines
'/pattern1/,/pattern2/' on lines from appearance of first pattern to the first occurence of the second pattern
Commands print, delete, change, append
These commands tell sed what to do with the content of the pattern space.
Caution:
Remember that the default action of sed is to print everyting which is in the pattern space after the commands on the line are executed.
This will lead to suprising doubling of lines when using print.
Use -n
flag to supress this behaviour.
Examples:
sed '1,2p' file
Will print the first lines twice each then the rest as normal.
sed -n '1,2p' file
Will print the first two lines, does not print the rest
### delete
`sed '1,2d' file` deletes first two lines
`sed '/pattern1/,/pattern2/d file` deletes lines from pattern1 containing line to pattern2 containing line
### change
`sed '1,2cXXXX file'` will replace the first two lines with a single line containing XXXX
In case you weant to have a multiline replacement use '\n' inside the string
### read
`sed '1,2rfile2' file1` will put:
* first line of file1
* whole file2
* second line
* whole file2
* the rest of the file
### substitute `s/pattern1/pattern2/gI`
To replace a pattern1 with a pattern2.
**Examples**
`sed 's/hello/goodbye/' file` will replace the first occurence of hello with goodbye on all lines.\
`sed 's/hello/goodbye/g' file` will replace all occurences (g goes for global).\
`sed 's/hello/goodbye/gI' file` will replace all occurences of hello case independently (Hello, heLLo and so on).\
To delete pattern use `sed 's/hello//' file` which will delete first occurence of hello.
To delete a pattern in specific range `sed '1,2s/hello//g' file` will replace all hello occurences on first two lines.
### Using regular expressions in substitute command
1. It is possible to use regular expressions for the patterns, like [a-Z][0-9],
2. It is possible to group the regular expressions and use them for the substitution
**Example:**\
`sed 's/_\([0-9]\)/_a\1/' file` will insert "a" before a first digit following an underscore.
# YAML
## Background and use-cases
Looks YAML is perfect for some of my use-cases:
1. Make a human editable textfile lists which can be converted between plain text file and csv
2. Use the YAML for supplying setting for BASH scripts
3. Use the YAML for supplying settings for R scripts
## YAML syntax
### key value pairs
`key: value`
### Lists(Arrays)
```YAML
fruits:
-apple
-orange
-banana
Dictionaries (mapping)
address:
street: 123 Main st
city: Brno
zip: 12345
Nested Structures
person:
name: John Doe
age: 30
children:
- name: Jane Doe
age: 10
- name: Jake Doe
age: 7
Multiline Strings
using |
or >
description: |
This is a multi-line string.
Line breaks are preserved.
Anchor and alias
&
is used to set what gets anchored and *
is used to recall.
Different parts can be overwritten
default: &default
name: Default Name
age: 30
person:
<<: *default
name: John Doe
YAML parsing by yq
Installation
sudo snap install yq
\
Usage
Make the testfile
name: John Doe
age: 30
address:
street: 123 Main St
city: Springfield
Networking
Resource
What do I want?
Figure out why i am not able to connect to my pizero over wifi
- Find out what are the ip addresses of the devices connected to a wifi network
Hypothesis:
- I have the name of the zero wrong
- It does not want to talk using hostname, only ip address
- there is some specific problem/bug connected to a hotspot from a mobile deviceO
Finding wireless access point ip address
ip route | grep default default via 192.168.88.1 dev wlp2s0 proto dhcp metric 600 sudo nmap -sn 192.168.88.1/24 sudo nmap -sL 192.168.131.115/24 sudo nmap -vv -sP 192.168.131.115/24 sudo nmap -sS -sV -vv -n -Pn -T4 192.168.131.115/24
Hardware commands
Resource
The ls* suite
lsusb
gives you list of all usb devices, can be useful to figre out whether usb is even detected.\watch -d lsusb
can enable you to go around the ports and test where it appears.\lsusb -t
gives you a tree view of the devices under the different busest\lspci
gives you a lot of info on the pci components.\lshw -html > hw.info
creates an html file with all the hardware spec. Truly amazing.\lshw -short
gives you shorter version.\lscpu
info about the cpu characteristicsi\lsblk
give you the info about the disks\watch lsblk
is super useful to run in paralell terminal to see adding and removing hardware you want to format and so on.
=======
Logging what happened for stack-overflow posts
- Make a troubleshoot file
touch troubleshoot
- Save the command into the file
echo "your command" >> troubleshoot
- Run the command and collect both stdout and stderr into troubleshoot
$( tail -n1 troubleshoot) &>> troubleshoot
- Check what happened
cat troubleshoot
Maybe there is an easier way, but this works well enough for me.
Mounting volumes
Motivation
- Be able to find what devices are connected to my machine
- Be able to mount the disk devices to a place where it is easy to use (for copying and stuff)
- Learn how to create linux and windows compatible USB
Resources
video on learn linux tv
lsblk
list block devices
- gives all the devices, the hard drives are sda and number\
- the usbs are sdb and number
- it also shows where it is mounted (for example the normal volume I have is mounted as / )
- if the device is not mounted automatically nothing is written there
- each disk device has a file in
/dev/sda
and like that lsblk -f
get the type of filesystem
sudo fdisk -l
gives info about the devices
- needs to be run with sudo
- gives more detailed information, make of the device, sectors size, disk label, disk identifier etc.
- the disk is split into devices (in case there are more partitions)
mount
list the mounted devices
list all the mounted devices, there is a lot, so most usefully grep for the disk name to get what you want.
mount device dir
mount the file where you want it
the trick is what you see in lsblk is sdc1 etc.
In linux everything is a file, and disks live in /dev/
folder, so when mounting it you must use the full path /dev/sdc1
\
example command:
mkdir /home/vladimir/usb
# make a folder where to mount
sudo mount /dev/sdb1 /home/vladimir/usb
mount the usb
the proper place to mount to is /media
for temporary disks like usebs
the proper place to mount a harddrive is /mnt
\
sudo umount dir
to unmount
just put the path to the directory you want to unmount, not the name of the device
df -h
how much of a filesystem is used
there is also an ncdu
utility which is more useful, but needst obe installed first whihc I did not do today
Reformatting USB to be windows and linux compatible
use parted to create a new partition table
lsblk
to find what are the devices (lets see we get our device on sdb)sudo parted /dev/sdb
start parted on this device(parted) mklabel msdos
will have some messages about:- use of partitions -> ignore
- data will be lost -> yes
- Error unable to inform the kernel -> Ignore
(parted) mkpart primary ntfs 1MiB 100%
(parted) quit
Format to NTFS
sudo umount /dev/sdb1
need to unmount the volume otherwise throws an errorsudo mkfs.ntfs -f /dev/sdb1
to formatlsblk -f
verify the partition and filesystem
if USB does not show up on Windows:
on windows:
Open Disk Management by pressingWin + X
and selecting Disk Management.- Look for the USB drive in the list of drives. If you see the USB drive but it doesn’t have a drive letter, you can assign one:
- Right-click on the partition and select “Change Drive Letter and Paths…”
- Click “Add” and assign a new drive letter.
- System volume information gets added to the usb and solves the problem
Input/Output error
On an SD card not able to write an image, not able to reformat (win), not able to proceed with parted (Input/Output) error.
- overwrite the SD card by zeros:
sudo dd if=/dev/zero of=/dev/sdb bs=4M status=progress
- try parted as above
- check the kernel messages:
sudo dmesg | tail
At the end decided to trash the SD card, was corrupted
Managing groups and users
Motivation
- Make new users
- Give them access to a shared folder
- Enable them to execute the same programmes
Resources
- [link to video from linode](link will be here)\
- [link to video about permissions in general](link will be here)\
- chapters from the linux administration book
Basic ideas:
- everything is a file
- permissions to files are granted to a. owner b. group c. all
- Permissions of the file are normally inherited, or can be user set or group set by setUID setGID
- At creation every user is added to a group bearing its name
- Each group can have multiple users
- Each user can be in multiple groups
- Many services (ssh, xrdp etc.) create a group, by adding the user there enables him to use that services
Basic commands:
useradd <username>
adds a user with default values
- base home directory for the user is created in the home directory
- the account does not expire
- there is no password created at the time of creating the user
- bash is selected as a default shell
- the user gets a group of his/her own
- it is possible to make a system user with an
useradd -r <username>
which is non-login and used for automation of tasks
Example code:
sudo useradd -s /bin/bash -m <username>
# to make the user
sudo passwd <username>
# to set the password
su <username>
change to the user account
xdg-user-dirs-update --force
create the desktop/downloads directories
groupadd <groupname>
creates new group
usermod -aG <groupname/s> <user>
add user to group
to remove user from group run usermod -G <all groups but the one you want to remove the user from> user
groups [user]
lists the groups of user
passwd [user]
create password
Using process redirection
there is an interesting concept of creating temporary files using the process substitution
syntax:
diff -y <(sort file1) <(sort file2)
\
echo diff -y <(sort file1) <(sort file2)
\
Useful commands
true
true
results in exit code 0
sleep
sleep
gives you sleep for a given time for seconds minutes hours days.
sleep 1s
or sleep 1m
and so on.
works also for the floating points.\
shift
shift
moves the positional parameters by [N] close to zero (defaults to 1 if not specified) and reduces the $# by
[N].
Returns exit code of 0 unless N is negative or greater than $#.
So basically you put it at the end of the while loop defined as while [[ $# -eq 1 ]]
I used it in a while loop to assign the first parametr into username and then shifted, this way the while loop exited
and the following code expanded the rest of arguments into the comment variable.\
basename
basename
strips the string leading up to the last string after a /
.
It works on strings so you can apply it to a string, and it will do its job despite the string being a path to a file
which does not exist.\
dirname
Strips the filename and gets the last directory.\
cut
Splits the standard input or a file based on characters, fields, delimiters etc.
Enables using ranges which can lead to some confusions.
There may or may not be a space between the -c
flag and thenumber or dash for ranges
Using the -c
flag with a range or a single field
echo "apple" | cut -c 2-4
gives you characters 2 to 4 > ppl
echo "apple" | cut -c -4
gives you characters 0 to 4 > appl
echo "apple" | cut -c 2-
gives you characters 2 to end > pple
echo "apple" | cut -c2
gives you character 2 > p
\
Using the -c
flag with a comma
echo "apple" | cut -c 2,4
gives you characters 2 to 4 > ppl
echo "apple" | cut -c 1-2,4-5
gives you characters 1 to 2 and 4 to 5 > aple
\
using the fields by -f and -d
flag
can be used to get the fields separated by a given separator, super useful for working with csv files
echo -e "1,2,3\na,b,c" > commatest
to create a comma separated file
cut -d "," -f 2-3 commatest
gives you the second and third column.
The delimiter needs to be a single character.
COnfusingly the -d
flag cannot stand alone, if you are splitting on comma, it must be -d,
or -d ","
better stick
to the more general syntax, because -d;
does not work.
variables in bash
man bash
and there /shell variables
to jump right there for definitions.
executing commands and programmes
There ares several important concepts and commands to know when it comes to executing commands and your own programmes.
- PATH variable
which
commandtype
commandhash -r
command/usr/local/bin
location where to keep the personal scripts (can be kept apart from the rest of the system in case you upgrade)
PATH for search of the commands
PATH is a bash variable which specifies the folders where the operation system goes to search for the commands(programmes) to be executed.
It starts with the lowest (closest to the user ) such as /usr/local/bin
and then goes more general to allow for the
customization of the commands.\
which
the which
command tells you where is the command you are interested in located.
which <command>
\
type
type
tells you what kind of a command it is whether it is a shell builtin or a proper programme outside of the shell.
type -a <command>
gives you all the locations of the command which are available.
Putting your own command into the path to be general and then removing it
Being able to write some small scripts which are available all the time is super powerful feature of linux enabled by
the abovementioned PATH variable.
Because PATH variable defines where the system looks for the commands, that allows you to create a command/script, copy it into a folder on the path and then use it from anywhere.
Example of creating a new head
command
Create a script called head
and put it into a /usr/local/bin/
.
Change the permissions for it to be executable.
This command will be executed first when I call the head
command.
Be careful when adding and removing your own commands.\
Their existence is not checked every time it is called. Instead it si hashed.
So after you remove your own command and you try to run it, it fails, because it goes to the place it remembers but does not find anything (instead of executing the next in line).
In case you run type <removed-command>
it returns > the <removed-command> is hashed
.
To make an update of these hashes run hash -r
and everything is okey again.\
Positional parameters
First look at the positional parameters:\
echo "you executed this command: ${0}"
gives you the name of the last command.
It is possible to omit the curly braces around the zero. It works the same but the curly braces are more foolproof.\
Expanding to number of positional parameters
${#}
or $#
expands to a number of the positional arguments supplied.
Can be very neatly used to give a help to the user.
In case the user does not supply any positional arguments tell them the usage of the command/script.\
if [[ "${#}" -lt 1 ]]
then
echo "Usage: ${0} USER_NAME [USER_NAME]..."
exit 1
fi
For loop through the positional parameters
for USER in "${@}"
do
echo " User: ${USER} "
done
Notes: it is important to quote the “${@}” in order to avoid splitting the user name which could contain spaces to separate fields.
While loop
Shell Scripting OCurse Adding the new users and modifications
Figure out what programmes is what
type <command>
find all types of the : type -a <command>
it is better to use the builtin is faster and will always work
to get help on builtin you cna use help
Understanding the UID and bash variables
UID is bash variable all bash variables are to be found in man bash
to get the username use the programme id
get the all the info id
get the user UID id -u
get the user group id -g
get all the groups ids id -G
get just the user name id -un
get just the group name id -gn
\
get the result of a command into a variable
USER_NAME=$(id -un)
check if the user is root:\
if [[ "${UID}" -eg 0 ]]; then echo "you are a root; else echo "you are not root"; fi
also tested here the strings\
if [[ "${USER}" = "${USER_NAME_TO_TES_FOR}" ]]
then
echo "your username matechs ${USER_NAME_TO_TEST_FOR}"
fi
Exit status
you can tell the script to exit by a specific exit code using exit[n]
the last exit status is stored in ${?}
variable
getting user input
using the read builtin to get user input into a variable called VAR:
read -p 'this is a prompt: ' VAR
In case there are more variables defined:
read -p 'this is a prompt: ' VAR1 VAR2 VAR3
the input is split at the delimiter. In case there are more of the pieces then variables the leftover goes into VAR3.\
Permissions
order of bits is: user, group, all, other users who are not ina file group.\ the values for the bit codes are as below:
- r=4
- w=2
- x=1
The defaul permission is chmod 755 (owner can modifiy it, others can just read it and execute)
to run the bashscript you need to use ./script syntax, because it is a file, not a programme (that runs just with script)
How to add a new local user
using the useradd
builtin. the LOGIN parameter is a username. By usage should not be longer then 8 characters, you can
yse numbers also. The too long names still work, but get
shortened in listings etc.
Creating the new name user: useradd dougstamper
Check that you can log into him: sudo su - dougstamper
The su -
starts it as a login shell which is better somehow\
In case you use -c
to get the comment field which can be used to put the whole name.
In case you want to create the home directory use the -m
flag.
The creation of the home directory is decided by the /etc/login.def config file, where in my case the CREATE_HOME is set
to yes. however it can be different on different systems so to make sure it always works, you should use the -m flag.
Deleting the user
to delete user run userdel <username>
. This command removes the user, but keeps the home directory, so in case you
make the same name of the user he/she will get the same home directory as the previous one.\
Set/change the password for the user
command passwd
activates the change of the password for the interactive shell.
In case I want to supply the password from the script I need to use the --stdin
flag.
To make sure that the user changes the his/her password I can use the -e
expire flag which will force the user to
change the password after first login.\
To change the password of the specific user you need to either be logged in as that user or do it as a root.
sudo passwd <user>
works\
In case you want to change the password from the script use the possibility of password coming from standard input using
echo: echo ${PASSWORD} | passwd --stdin
\
Installing ivrtual box and vagrant
resources
virtual box link following the command line options wget -q https://www.virtualbox.org/download/oracle_vbox_2016.asc -O- | sudo apt-key add - sudo add-apt-repository “deb [arch=amd64] http://download.virtualbox.org/virtualbox/debian $(lsb_release -cs) contrib” sudo apt update && sudo apt install virtualbox-7.0
vagrant installation copy paste to the terminal wget -O- https://apt.releases.hashicorp.com/gpg | sudo gpg –dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg echo “deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main” | sudo tee /etc/apt/sources.list.d/hashicorp.list sudo apt update && sudo apt install vagrant
The rename command (needs to be installed on 20.04)
Motivation and use cases:
- replace some common characters “-”, " “,”_",
- remove a matching pattern - only one or greedy
- add something to the start, to the end
- remove something from the start, from the end
- know how to do the dry run
- know
Resources
Basic usage
rename [ -v ] [ -n ] [ -f ] perlexpr [ files ]
-v is verbose, prints the names of the files successfully renamed -n no act, shows the files that would be renamed -f force overwrite existing files
Perl syntax
The rename follows perl syntax s/pattern1/pattern2/[gi]
\
metacharacters:
- ^,$ to match the start and and
- ., +, ?, any character, preceding characters once or more, zero or one
- | or operator
- (…) grouping
- […] set of characters
- [^…] set of characters to be excluded
- \t is a tab, \n is a newline, \r is a carriage return
- \d is a digit \D is a non-digit
- \w is a word character (alphanumeric or underscore), \W any single non-word character
- \s matches single whitespace (space, tab, newline), \S single non-whitespace
- \b zero width matching word boundary \B zero width matching all but not word boundary
- \
- {n[,[n]]} are the quantifiers
- (pattern){n} - matches exactly the number
- (pattern){n,} - matchs n and more
- (pattern){n,m} -matches from n to m occurences There is a lot, let me settle with this.
Examples
replace characters
files: a-b-c c-d-e
to replace the first matching character:
rename -n -v 's/-/_/' *
output:\
rename(a-b-c, a_b-c) rename(c-d-e, c_d-e)
-n -v flag tells you what gets renamed
to replace all the matching characters in all files ("*"):
rename -n -v 's/-/_/g' *
replace the extension
rename -n -v 's/\.jpg/\.jpeg/g'
remove two different extensions
rename -n -v 's/(\.jpg|\.jpeg)//g'
add extension
rename -n -v 's/$/\.jpg/g'
translate from one character set to another
rename 'y/[a-z]/[A-Z]/'
in case you try to rename to something which already exists, does not do it unless you use the -f flag.
using the regex lookups
replace the last dash preceding the last character, which is a digit.
rename -n -v 's/-(?=\d$)/_/'
replace every dash preceded by a digit.
rename -n -v 's/(?<=\\d)-/_/'
remove spaces replace with underscores
using the string substitution and enabeling substitution of one or more spaces with an underscore:\
rename -n -v 's/\s+/_/g' <files>
Be aware, that using translate does not work!
I guess it is because \s
is not a character.\
rename 'y/\s/_/' <files> # doesnt work
remove spaces and dashes with underscore
rename -n -v ’s/\s+|-/_/g'
replace weird characters to underscores as alias
rename dot, comma,semicolon,space, plus, question mark and dash to underscore to get “word” formatted name. Dot preceding extension (composed of digits and letters) is kept
alias to_underscores_test="echo 'this is testmode, use to_underscore_run command to rename'; rename -v -n 's/(\,|\;|\s|\+|\?|-|(\.(?!(\w|\d)+$)))+/_/g'"
alias to_underscores_run="rename -v 's/(\,|\;|\s|\+|\?|-|(\.(?!(\w|\d)+$)))+/_/g'"
Authorizing pushing to github from command line gpg
and pass
Resource
link to generate gpg public/private keys
Issue
- when I tried the
git push
from repo, wanted to get the \
Done
- searched for the gpg keys:
find ~/ -name .gpg-id -print
not found - checked for the gpg presence by searching for version:
gpg --version
- installed
gpg
by:apt install gpg
- generated the gpg key:
gpg --full-gen-key
, used gmail email - installed
pass
by:sudo apt install pass
- initialized pass by:
pass init [email protected]
Notes
- works
- the and passprase is stored in bitwarden
- is an email you put in when creating the password
How to set up the protected instance on linode 02-02-2023
- made linode mbd-lnx-01 user vld a root
- passwords are in bitwarden
- did the securing as in the docslink
- super useful to put an alias to log in
- useful to add the IP address of the linode to ~/.profile and ~/.bashrc
- learned how to generate the keys
- set the keys in github to be able to communicate direactl from the command line
- installed csvkit, youtube-dl, and some other stuff lost now in it
- was not happy with the filezilla, so will use the sftp link
- big idea is to go through it and make a script which would enable me to run it automaticaly (also with the .vimrc and aliases etc)
26-11-2022
need to learn how to use the arrays, expansions of indices etc.
However the thing I need to do most is to clean this directory to have proper organization of the files so that I can fing what i need. What I am not able to find/do not search because it is not comfortable, is lost and have no purpose to keep it.\
Get the version of your ubuntu
20-11-2022
lsb_release -a
remap the capslock into esc key
for xfce
I followed following instructions link
and added this:
/usr/bin/setxkbmap -option “caps:swapescape”
into the autorun startup from the applications menu
works very well so far
20-11-2022
I followed this:link
put ['caps:escape']
into the dconf tool which was activated in terminal running: dconf-editor
.
dconf-editor
installed using these commands:
sudo add-apt-repository universe
sudo apt update
sudo apt install dconf-cli dconf-editor
rks
Learning the basics of a find command
02-09-2022
Motivation
Parsing output of ls into a variable and then executing commands is not a safe way.
According to bash pitfalls website there is a better way, the find
command.
The find command is able to find stuff and then do something with it.
So lets go and explore:)\
Pitfall No1
I have several files with .mp3 suffix made by following line:
touch "**.mp3" "normal.mp3" "with break.mp3" "with a \n.mp3"
ls
fail
I want to use ls
command to do something with these files:\
find00.sh
#/bin/bash/
for i in $(ls *.mp3); do
echo ${i}
done
`
Output ls fail:
**.mp3
normal.mp3
with a \n.mp3
with break .mp3
normal.mp3
with
a
\n.mp3
with
break
.mp3\
This and other variations like ls
or find . -type f
etc are all wrong
The reason is that there can be spaces, newlines, globbing characters and even “`” characters in the filenames.
And that messes up the function of a script.\
Additionally, the ls command works differently on different systems,
its main role is to make a human readable output. Thats it all it does.\
Normal globbing
find01.sh
#/bin/bash for i in ./*.mp3; do\ echo "$i" #always use double-quotes\ done
Output normal globbing
./**.mp3
./normal.mp3
./with a \n.mp3
./with break .mp3\
However if there are no files found, the loop will still execute ones,
because there is the “./*.mp3” in the $i variable.\
Output normal globbing without matching files
./*.mp3
To avoid this behaviour, there should be a test for existence of the file.\
Normal globbing with a test for file match
*find03.sh
#/bin/bash/ for i in ./*.mp3; do [ -e "$i" ] || continue echo "$i" done
This gives no output and therefore I can say it works.
Testing steps summary:
touch "**.mp3" "normal.mp3" "with break.mp3" "with a \n.mp3"
./find00.sh>>output
./find01.sh>>output
./find02.sh>>output
rm ./*.mp3
./find01.sh>>output
./find02.sh>>output
Pitfall-01: find
find03.sh
#!/bin/bash find . -type f -name '*.mp3' -exec echo {} \;
works both on the empty and normal folder with *.mp3 files.\
Overall the find command is super useful and would be good to learn more, so lets go and do it now.
What I would like to achieve eventually is to be able to move around files and give them the name according to either my selection or based ont he name o fhteir parent folder if it is somehow possible.
Find in more detail
- find descends through a hieararchy of files
- matches files which meet specified criteria
- does stuff to them
Example 1 - most basic find
find .
- you should always specify, where you want to search!\
- if you do not specify any criteria, you get all the types of files blocks, sockets etc.* if you do not specify an action, most find versions will print, it is always better to specify thus:
find . -print
- it does not sort the output at all
Example 2 - find files by criteria
find . -name '*.mp3' -print
- find uses globs. These globs need to be protected from the shell expansion, thus the single quotes
Example 3 - find files by criteria using logical operators
find . \(-name '*.mp3' -o -name '*.jpg'\) - prin
find . (-name ‘.mp3’ -o -name ‘.jpg’) - print
t`
so the and operator is implicit, the OR needs to be specified by the -o flag.\
additionally the -name flag searches only for the basename of the file.
In case you want to search in the folder names you must use the flag -path.\
that is a lot I learned today must stop now.
26-08-2022
SCP
From my computer to the remote
scp myfile.txt remoteuser@remoteserver:/remote/folder/
From remote to my computer
scp remoteuser@remoteserver:/remote/folder/remotefile.txt localfile.txt
Also works recursively
scp remoteuser@remoteserver:/remote/folder/remotefile.txt localfile.txt
So lets try it and see now
need to get the address of the ssh connection
ss | grep -i ssh | awk 'F" " {print $NF}'> cloud-desktop-ssh
gives me the number and :ssh
as a file in home directory and here when I delete the :ssh I can also make it a variable this way:
CLOUD="vld@
cat ../cloud-desktop-ssh"
but it is super tiring, there must be something better, at least to have it as an environmental variable forever
SFTP
How to use it
- Navigate to the folder with the documents you want to copy to remote/where you want to recieve the files
- get into the remote machine using sftp
- figure out where you are and navigate where you want to get
- upload or download files
1. Navigate where you want to get on local machine
Note: whatever starts with a ‘#’ is a comment explaining the command
pwd
# to see where you arecd
# to get where you wantcd ~
# gets you to home directorycd ~/Desktop
# gets you to Desktopcd ~/Documents/
# gets you to Documentscd ~/Music/
# gets you to Musiccd ~/Videos/
# gets you to Videoscd ..
# gets you to the parent directorycd -
# gets you to the last visited directory
ls
# to see what files are in the directory
2. Log into the remote machine using sftp
sftp [user@]<remote-ip>
Note: The prompt will change to >
and lose colours
3. Navigate the remote and local directories
To navigate through the file system of the remote machine use the same commands as you used on the local machine before
Notes:
-
In case you want to go back to the local machine and navigate the filesystem there, put
l
before the normal commands. -
The expansion for home directory does not work in the sftp mode
-
All the paths in sftp are relative, start from pwd and append whatever path you say so say if you are in
/home/username/Documents
and you typeput *.jpg /home/username/Videos
the computer will create a path/home/username/Documents/home/username/Videos
and throw an error. -
pwd
is working directory on remote;lpwd
is working directory on local -
cd
change directory on remote;lcd
change working directory on local
This works for all the “normal commands” (pwd
, cd
, cp
, mv
, rm
etc.)
4. Upload (put
) and download (get
) files to and from remote
put *.jpg
# uploads all .jpg files from local working directory to the remote working directory
Overview of some commands and flags
Note: whatever starts with a ‘#’ is a comment explaining the command
put
# to copy a file from local to remoteget
# to copy from remote to the local!
# drops me into the local-r
# recursive-P
# copy permissionsdf -h
# tells you the space on the disk where the folder is!?
# gives you helpcd
# change remote directorylcd
# change local directorypwd
# remote working directorylpwd
# local working directorycp
# copy on the remotelcp
# copy on the localmv
# move/rename on the remotelmv
# move/rename on the local
Little bit of awk
this gives you the size of all the files containing shiny
in the given folder field number $5 is the size
ls -la |grep shiny | tail -5 |awk 'F" " { size=size + $5; print $5 } END { print "total size is " size/(1024*1024) "M" }'
ALiases
14-08-2022
Motivation
Be able to execute the commands which I do more common without typing out so much
Examples:\
- convert by pandoc from md to pdf, md to docx and docx to md
- download the mp3 or mp4 from a youtube link
General
There is a ~/.bashrc
file where I can put the aliases uses a convention alias CMD1='CMD2'.
The ~/.bashsrc
file needs to be first copied to ~/.bashsrc.bak
by cp ~/.bashrc ~/.bashrc.bak
After modifying the file needs to be sourced, not executed: . ~/.bashrc
Cleaner way to do it is: to make a file called ~/.bash_aliases
where I put the aliases and put following in the ~/.bashrc
:
if [ -f ~/.bash_aliases ]; then . ~/.bash_aliases fi
Resources:
Test
ll
alias ll='ls -l'
Steps
- cp ~/.bashrc ~/.bashrc.bak
- echo “alias ll=‘ls -l’” > ~/.bash_aliases
- echo “if [ -f ~/.bash_aliases ]; then . ~/.bash_aliases; fi” » ~/.bashrc
- . ~/.bashrc WORKED!
now do it by a script! MAybe later!
reverse back
- mv ~/.bashrc.bak ~/.bashrc
- . ~/.bashrc
write the create_aliases.sh script
- #!/bin/bash/
- echo “cp ~/.bashrc ~/.bashrc.bak” &&
- echo “alias ll=‘ls -l’” > ~/.bash_aliases
- echo “if [ -f ~/.bash_aliases ]; then . ~/.bash_aliases; fi” » ~/.bashrc
- . ~/.bashrc WORKED!
The power of symbolic links
13-08-2022
Motivation
To have the files better organized, have them at one place and call them from various places if needed.
General
The symbolic links enable you to have one source file/folder and approach it from different places by symbolic links. YOu can modify the file content, but when you delete it, it is just the link, which was deleted.
Syntax
ln -s
creates a symbolic link ln
creates hard link, if you delete the hard link, the original is gone too.
Unless you know what are you doing, use the symbolic links!
TARGET only
To make a symbolic link leading to a file/folder in a place with [TARGET] path into current folder.
the name of the link is the same as the name of the original
ln -s [TARGET]
New name of link
to make a symbolic link with a brand new name [LINK_NAME] which directs to file/folder in a place with [TARGET]
ln -s [TARGET] [LINK_NAME]
Important Better use the full path strarting with ~/
because otherwise the symbolic links do not work from the
desktop
link a directory under a new name
ln -s [TARGET] [DIRECTORY]
*the directory is created by this command, shell not have a “/” at the end otherwise it does not work
You can have multiple symbolic links leading to the original file
Exploring the for loops to rename and move files
11-08-2022
Motivation
- Be able to name the files in the folders according to a name of the subfolder
- Copy these files into a parent folder
- Make one file containing all the information in the files
Prepend the names of the files in the folder to the filenames
- make variable for directories
DIRS="AA BB CC"
- make directories
for i in $DIRS; do mkdir ${i}; done
- make test file in the directory
for i in $DIRS; do touch ${i}/test1; done
- get the variable with directories names as if I did not know it
DIRS2=
ls
(without the space)
do not know how to get only directories here, not files - write a text in each file
for i in $DIRS2; do echo ${i} > ${i}/test1; done
- pre-pend the directory name and copy to parent folder
for i in $DIRS2; do cp ${i}/test1 ./${i}_test1
- summarize everything into one file:
touch summary.txt; cat * > summary.txt
throws and error as there are directories involved in the expansion but gives the summary anyway
would be great to be able to include the names of the files it comes from as a first line in the file
BASH history
link
another useful link on the bash history and rerunning commands stuff here
To see history
history
Add timestamps
export HISTTIMEFORMAT='%F %T '
Using for loop to manipulate the same file in multiple directories in working folder
2022-08-10
Motivation
Append the same line to an INFO.txt file which is in directories called CMDX_[and here it is a mess]
How to do it
DIRS=ls | grep CMDX
for d in $DIRS; do echo "Same line" >> "${d}INFO.txt"; done
To figure out
- is
"${d}INFO.txt"
safe or is"$"{d}"INFO.txt"
better?"$"{d}"INFO.txt"
does not work
- when using with touch to make .txt files, why does it says that it does not have rights, but does the job anyway?
- Why is the line not appended, but added to the end in those INFO.txt files? Worked on the new ones I created.