There are three file descriptors open by default:
0 for stdin
1 for stdout
2 for stderr
Per-line settings (temporar redirection)
# stdout to a file
ls /usr 1>out.txt
# stderr to a file
ls /usr 2>out.txt
# both stdout and stderr to a file
ls /usr &>out.txt
Truncate a file. The colon is optional (in BASH) but in some shells required.
: > truncate.me
Prompt for delete confirmation for each file, i.e. the interactive mode of rm
, store in .bashrc
:
alias rm='rm -i'
Sha256 with Openssl
cat $filename | openssl dgst -sha256
openssl dgst -sha256 <filename>
Less secure md5
md5 $filename
Encrypt (you'll be asked to choose a password)
# -a will be base64 encoded so it can be pasted as ASCII
openssl aes-256-cbc -a -salt -in <file.zip> -out <output.enc>
Decrypt
# -d for decrypt
openssl aes-256-cbc -d -a -in <input.enc> -out <origianlfile>
Round a floating point number $f
to $n
decimal points.
printf "%.*f" $n $f
Use bc
for arithmetics. Add -l
(--mathlib
) for the standard math library to be included.
bc -l <<< "42 / 12"
Sum a series of numbers.
awk '{i+=$1} END {print i}' data_series.txt
AWK uses dynamic variables and i
is zero by default, see AWK's man page
Uninitialized variables have the numeric value 0
Read file by line and split the line of whitespace into columns
while read -r col1 col2 ...
do
echo $col1
done < $FILENAME;
Basic function with two arguments and the invocation of the said function.
function foo {
FIRST_ARG=$1
SECOND_ARG=$2
}
foo "abc" "xyz"
#!/bin/bash
if [ "$EUID" -ne 0 ]; then
echo "Please run as root"
exit 1
fi
# e: exit on error
# u: exit on unset variable
set -eu
# Print file descriptors in use by a process
ls -l /proc/${PID}/fd
# Print open network connections of a process, and how to close a selected one below
# lsof -n -i 4 -a -p ${PID}
COMMAND PID FD TYPE DEVICE SIZE/OFF NODE NAME
vlc 26133 3u IPv4 21652774 0t0 UDP 192.168.1.1:46833->192.168.1.2:2001
vlc 26133 4u IPv4 21652775 0t0 UDP 192.168.1.1:46834->192.168.1.2:2002
vlc 26133 5u IPv4 21652776 0t0 UDP 192.168.1.1:48852->192.168.1.3:2001
vlc 26133 6u IPv4 21652777 0t0 UDP 192.168.1.1:48853->192.168.1.3:2002
# Issuing the command 'close(3)' will close the file descript 3u (3=number, u= unsigned?) if done as below using gdb:
# echo -e "call close(3)\nquit" > gdb_commands
# gdb -p 26133 --batch -x gdb_commands
> man ps|grep -A 20 'output specifiers'
Here are the different values that the s, stat and state output specifiers (header "STAT" or "S") will display to describe the state of a
process:
D uninterruptible sleep (usually IO)
R running or runnable (on run queue)
S interruptible sleep (waiting for an event to complete)
T stopped, either by a job control signal or because it is being traced
W paging (not valid since the 2.6.xx kernel)
X dead (should never be seen)
Z defunct ("zombie") process, terminated but not reaped by its parent
For BSD formats and when the stat keyword is used, additional characters may be displayed:
< high-priority (not nice to other users)
N low-priority (nice to other users)
L has pages locked into memory (for real-time and custom IO)
s is a session leader
l is multi-threaded (using CLONE_THREAD, like NPTL pthreads do)
+ is in the foreground process group
# Search in files, get the line number reference:
grep -Hn '8080' server.js | cut -f1,2
# -iname = ignore case mask
# -name = case sensitive mask
# -type f: file, d: directory
find /search/under/here -iname *.js -type f
sed '/yourregex/!d' foo.log
sed 's/matchthis/replacewiththis/g' bar.txt
Replace multiple strings with the same string:
sed 's/one|two|three/four/g' bar.txt
Replaces any one
, two
, or three
with four
Use sed
as a filter in find
find ./src -type f -exec sed 's/\t/ /g'
Change CRLF file to LF
tr -d '\r' < input.txt > output.txt
I use the jq
program
cat package.json | jq .author.name
"Foo Bar"
Change permissions to your key and .ssh directory:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_rsa
chmod 600 ~/.ssh/authorized_keys
chmod 644 ~/.ssh/id_rsa.pub
Display file permission in octal format:
unix: stat -c '%a' ~/.ssh/id_rsa.pub
sshd config files are usually in /etc/ssh/sshd_config
, restart the daemon after changing the config by sudo service ssh restart
client config for ssh is usually in /etc/ssh/ssh_config
. to use ssh key login to from hosts user1@A to user1@B, add A's public key to B's authorized keys file, which is configured in sshd_config
and is usually /home/user1/.ssh/authorized_keys
. The authorized keys file must be readable only by root and no one else (chmod 600 ~/.ssh/authorized_keys
).
While connected to a host through ssh, the default escape character "~" can be used with some of these commands (more available):
~?
to display the list of escape characters~.
to disconnect
Auto rebase on pull in ~/.gitconfig
git config --global pull.rebase true
Pretty format git logs
# show only filenames of a commit
git show --pretty="format:" --name-only bd61ad98
git show --pretty="format:" --name-only HEAD~5
Reverting commits
# revert
git help revert
git revert --no-commit REF
git revert HEAD~3..HEAD # last three commits
# Compile a C program that uses MySQL connection
gcc -o output_file $(mysql_config --cflags) source_file.c $(mysql_config --libs)
This environmental variable gets executed in bash every time the prompt receives a command.
if [[ "$TERM" == screen* ]]; then
do_something_with_screen() {
}
PROMPT_COMMAND="do_something_with_screen; $PROMPT_COMMAND"
fi
Scan address and port using netcat
nc -uvz <address> <port>
u
for UDP,v
for verbose,z
for scan only, without sending data
Inspect which ports are listening
sudo netstat -tanp
Restart network manager on system resume
#!/bin/sh
# place this in /usr/lib/pm-utils/sleep.d/A_restart-network-manager
# and sudo chmod +x /usr/lib/pm-utils/sleep.d/A_restart-network-manager (give it the same permissions as the other files in the folder have)
case "$1" in
resume)
service network-manager restart
esac
Restart the network manager.
# restart network manager
sudo service network-manager restart
# see all packets with source or destination 127.0.0.1
$ sudo ngrep host 127.0.0.1
sudo tcpdump -A -n 'src host 127.0.0.1 and (((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0)'
$ nmcli general status
$ nmcli con up id <connectionid> # start connection
$ nmcli con down id <connectionid> # stop connection
$ sudo route -n
Add a static route for packets with destination 192.168.1.1 to go through a gateway 4.5.6.7
$ sudo route add -host 192.168.1.1 gw 4.5.6.7
Measures the total time
, dns lookup
, connection time
, and time to start transfer
curl -w '\n %{http_code},%{time_total},%{time_namelookup},%{time_connect},%{time_starttransfer} \n' https://example.com
My ~/.screenrc
:
# An alternative hardstatus to display a bar at the bottom listing the
# windownames and highlighting the current windowname in blue. (This is only
# enabled if there is no hardstatus setting for your terminal)
hardstatus on
hardstatus alwayslastline
hardstatus string "%{.bW}%-w%{.rW}%n %t%{-}%+w %=%{..G} %H %{..Y} %m/%d %C%a "
defscrollback 5000
# This polls the 'stat' command on a given file and when the output
# of that command differs to the output from the previous reading,
# it executes the specified commands.
while true
do
# In this case the command is 'stat -t %s ...' that outputs
# the timestamp in seconds of the file's last change.
ATIME=`stat -t %s ${FILE_TO_WATCH}`
# when the file is changed, the code branch in the if statement
# will be executed
if [[ "$ATIME" != "$LTIME" ]]
then
echo "${FILE_TO_WATCH} has changed"
bash ${CMDS_TO_EXECUTE}
LTIME=$ATIME
fi
sleep 5
done
Use watch
to check the CPU load. NB. Older versions of watch
did not support color output.
# Watch the average CPU load
watch -n 1 "(uptime | awk '{ print \$8 \$9 \$10 }')"
Create a new dir and change into it right away:
mkdir newdir && cd $_
cal
See man
page for options. Linux's cal
can show more than one month but I couldn't find this option in MacOS sierra
To have the settings from .bashrc
in a login session of BASH, add the following to ~/.bash_profile
:
if [ -f ~/.bashrc ]; then
source ~/.bashrc
fi
alias dir='ls -la'
alias ll='ls -alF'
alias gia='git add'
alias giaa='git add *'
alias gis='git status'
alias gil='git log'
alias gid='git diff'
alias gic='git commit -m'
alias branches='git branch -a'
export PS1="\[\033[36m\]\u\[\033[m\]@\[\033[32m\]\h:\[\033[33;1m\]\w\[\033[m\]\$ "
export CLICOLOR=1
export LSCOLORS=ExFxBxDxCxegedabagacad
Contents of ~/.gitconfig
:
[user]
email = tomas.libal@unrulymedia.com
name = Tomas Libal
[color]
ui = true
[alias]
today = log --since=\"6am\" --author=\"Tomas Libal\"
[push]
default = simple
Instead of configuring ~/.vimrc
I use Spacemacs, which is essentially an Emacs configuration directory ~/.emacs.d
stored in a Git repository:
git clone --recursive https://github.com/syl20bnr/spacemacs ~/.emacs.d
Set a custom home page by setting the WWW_HOME
env. variable, e.g. in ~/.bashrc
:
WWW_HOME='https://duckduckgo.com'
export WWW_HOME
lynx -listonly -image_links -dump ${URL}
Sometimes brew install lynx
will install it without the HTTPS support. To enable it, run brew edit lynx
, and add the following line to the ./configure
: "--enable-gnutls-compat",
. Then uninstall lynx and install it again (this will force the installation to use the updated recipe).
Print the message of the day on opening new terminal session by adding cat /etc/motd
to ~/.bashrc
Add this to ~/.bashrc
echo "Existing screen sessions"
screen -ls
List crontab for a given user crontab -l
or edit it crontab -e
.
Cron runs as its own user with no environment variables like PATH. You can set these variables in the Crontab file before the cron lines. Eg.:
SHELL=/bin/bash
PATH=/user/local/bin
...
Use crontab to run a target on reboot:
> crontab -e
# run this on startup:
@reboot /path/to/exe
The time and date fields and their allowed values:
minute 0-59
hour 0-23
day of month 1-31
month 1-12 (or names)
day of week 0-7 (0 and 7 are Sunday, or names)
Add a job that runs every day at 05:10am:
> crontab -e
# minute hour day-of-month month day-of-week
# asterisk=every minute/hour/day/month
10 05 * * * /path/to/exe
Add a user to a group
sudo usermod -aG $group $user
If the group does not yet exist, create it with sudo groupadd <groupname>
Add a user
-e
sets expiry on the user account-G
group membership (group has to already exist)-p
password (encrypted withcrypt
)-M
do not create the home directory-m
create the home directory if it does not exist
useradd <username> -e <YYYY-MM-DD> -G <group1,group2,...>
Set user password
passwd <username>
Switch between users as a super-user
su - <username>
See groups
# groups
See user's groups
# groups <username>
List failed logins (btmp
is a binary file so it need to be read with the last
utility)
last -f /var/log/btmp
Logins
last
# or
lastlog
GNU acct https://www.gnu.org/software/acct/
Install it
sudo yum install psacct
Provides
ac -d
summarises login timeslastcomm <username>
last commands per userlastcomm <command_name>
last invocationssa
summarises previous commands (all commands, all users)
RHEL 6+ auditing: http://people.redhat.com/sgrubb/audit/
sudo yum install audit
Audit reports
aureport # system wide report
aureport -au # authentication report
Permanent audit rules are at /etc/audit/audit.rules
# log every read and write to sshd_config
# in /etc/audit/rules.d/audit.rules
-w /etc/ssh/sshd_config -p warx -k sshd_config
Search failed login attempts
ausearch --message USER_LOGIN --success no --interpret
Keystroke logging
In both /etc/pam.d/system-auth
and /etc/pam.d/password-auth
add
session required pam_tty_audit.so disable=* enable=<username>
(does not record keystrokes when is in password entry mode, although this can be further enabled with log_passwd
appended to the line). Report is generated by aureport --tty
In RHEL derivatives this might be a service gdm status
or service lightdm status
. When stopping it, you might be presented with a text tty. If not, a shortcut <Ctrl><Alt>+<Fn>
where n=1-6
switches between text terminals.
ssh -Y user1@host firefox
Default bidning is same as in screen
which is Ctrl+b
C-b % vertical split
C-b " horizontal split
C-b <up> move to the pane above
C-b <down>
C-b <left>
C-b <right>
C-b : respawn-pane -k # this one respawns the pane if stuck in some process
When docker attach <container>
doesn't work then the following also logs you into the container's term
docker exec -it <container> bash
remove the header
tr -n +2 file.csv > no_header_file.csv
select n-th column
# this selects 1st, 3rd, and 7th columns from data.csv
cut -d, -f1,3,7 data.csv > output.csv
run a command on each file in the directory tree. Notice the {}
placeholder which will replace the file's path there.
search <dir> -type f -exec <command> {} <arg1> ... <argN> \;
E.g. shred every file inside the folder tree
search <dir> -type f -exec gshred {} --remove \;
This is a GNU implementation of OpenPGP
yum -y install gnupg
Public/Private Key operations:
# first time use you need to generate your key
gpg --gen-key
# check the public key
gpg --keyid-format long --with-fingerprint SomePublicKey.asc
# import the public key
gpg --import SomePublicKey.asc
# you'll need to sign this key, so first find it in your list of keys
gpg --list-keys
# find the two lines that correspond to the imported key:
# pub 3082A/<name-of-the-key> 2019-01-01 uid
# Name of the Person/Company
# accept the key by issuing:
gpg --sign-key <name-of-the-key>
# now you can verify a message/file
gpg --verify Something.zip.asc Something.zip
Encrypt/Decrypt
gpg --output someFile.gpg --sign --encrypt --recipient someone@example.com someFile.txt
# shorthand (outputs <original-file>.gpg
gpg -se -r someone@example.org someFile.txt
gpg --output someFile.txt --decrypt someFile.gpg
Symmetric key encrypt
gpg --output doc.gpg --symmetric doc
Enter passphrase:
Decryption using the --symmetric
scheme is done using the same --decrypt
command. You will be prompted for the passphrase.
Exporting your keys
# -a option is for ASCII. Default is binary
gpg --export-secret-keys -a UID > secret.asc
gpg --export -a UID > public.asc
Generate a revokation certificate
gpg --gen-revoke UID
In my version of GnuPG this generates the ascii version of the revocation certificate.
Signing:
gpg --output <document>.sig --sign <document>
gpg -u 0xDIFFKEY --output <document>.sig --sign <document>