/etc/default/grub
配置文件, 用于一些基本的修改项,
如默认启动项, Grub 界面等待时长, Grub 主题 etc.
More details in info -f grub -n 'Simple configuration'
# Default Startup OS
GRUB_DEFAULT=0
# Default Timeout
GRUB_TIMEOUT=5
# https://github.com/vinceliuice/grub2-themes
GRUB_THEME="/boot/grub/themes/Tela/theme.txt"
/etc/grub.d/*
生成/boot/grub/grub.cfg
的执行脚本(update-grub
命令),
可以更细致地修改启动项, 如各个启动项的名称、顺序等.# root commander
bcdedit /set "{bootmgr}" path \EFI\ubuntu\grubx64.efi
sudo add-apt add-apt-repository ppa:yannubuntu/boot-repair
sudo apt update
sudo apt install boot-repair
boot-repair
ssh-keygen -t rsa
ssh-add ~/.ssh/id_rsa
/etc/ssh/sshd_config
sudo systemctl reload sshd
sudo service restart sshd
~/.ssh/config
:
ssh user@ip
ssh user@ip
ssh -i file
Host github.com
HostName github.com
PreferredAuthentications publicKey
IdentityFile ~/.ssh/id_rsa
Host cs.github.com
HostName github.com
PreferredAuthentications publicKey
IdentityFile ~/.ssh/cs
Host cloud
HostName xx.org
User root
IdentityFile ~/.ssh/dsl_private_key
Host bwg
HostName 23.106.150.152
User root
Port 29692
git clone git@github.com:user/repo
git clone git@cs.github.com:user/repo
ssh -qTfnN -D 7070 bwg
google-chrome socks5 127.0.0.1 7070
rsync -ax -e 'ssh -c blowfish' /root/start_dir root@x.x.x.x:/root/dest_dir
sshpass -p "$DEPLOY_PASSWORD" \
scp -o StrictHostKeyChecking=no \
-P $DEPLOY_PORT \
-r ./build $DEPLOY_USER@$DEPLOY_ADDR:/var/www/html
包含路径命令 ./vmtools.pl >别名命令 >bash 内部命令 >$PATH 包含目录内的命令 /bin /sbin
man hier
通过源码包安装的软件,可以通过 ./configure --prefix=/opt/
/usr/src
: Kernel source code./usr/share/applications
: Desktop shortcuts./usr/share/fonts/opentype
: Open Type Fonts (OTF)./usr/share/fonts/truetype
: True Type Fonts (TTF)./etc/nginx
: Nginx.export LANG=en_US
xdg-user-dirs-gtk-update
export LANG=zh_CN
sudo locale-gen zh_CN.GBK
sudo locale-gen zh_CN.GB18030
sudo dpkg-reconfigure locales
Nightly build for Numix Circle icon:
sudo add-apt-repository ppa:numix/ppa
sudo apt update
sudo apt install numix-icon-theme-circle
GTK/GNOME themes located in /usr/share/themes/
or ~/.themes/
:
# Vimix Cursors Installation
git clone https://github.com/vinceliuice/Vimix-cursors
sudo ./Vimix-cursors/install.sh
# WhiteSur GNOME theme Installation
git clone https://github.com/vinceliuice/WhiteSur-gtk-theme
sudo ./WhiteSur-gtk-theme/install.sh -t all -i ubuntu
# Tweak for Firefox
sudo ./WhiteSur-gtk-theme/tweaks.sh -f
# Tweak for Snap Apps
sudo ./WhiteSur-gtk-theme/tweaks.sh -s
# Tweak for GDM
sudo ./WhiteSur-gtk-theme/tweaks.sh -g -i ubuntu
# Tweak Help Docs
sudo ./WhiteSur-gtk-theme/tweaks.sh -h
Repair for not detected HDMI problem:
sudo dpkg-reconfigure gdm3
sudo apt install --reinstall gdm3 lightdm ubuntu-desktop
sudo apt install chrome-gnome-shell
.extensions.gnome.org
to install extensions.mkdir -p ~/.local/share/fonts/
cp -fr code-fonts ~/.local/share/fonts/
fc-cache -f -v
fc-list
fc-list : family | sort | uniq
less /usr/share/aif/docs/official_installation_guide_en
pacman -S lynx arch-wiki-docs arch-wiki-lite
lynx /usr/share/doc/arch-wiki/html/index.html
systemctl enable dhcpcd
reboot
pacman -S --needed base-devel git wget jshon expac yajl zsh vim
curl -L -O https://aur.archlinux.org/cgit/aur.git/snapshot/package_name.tar.gz
cd package_name
less PKGBUILD
less package_name.install
makepkg -si
# -s sync deps
# -i install
# -r rm deps
# -c clean up
# packages' list
wget https://aur.archlinux.org/packages.gz
权限(user/group/other) 引用计数 user group 文件大小 文件修改时间 文件名
print working directory
无需参数(改名+移动)
link: create .bak/.hard
(硬链接) and .soft
(软链接:创建链接时填写绝对路径).
ln [源文件] [New Hard Link File]
ln -s [源文件] [New Soft Link File]
/etc/profile 中修改 HISTSIZE !n/!!/!字符串 重复执行第 n 条/上一条/指定开头的历史命令
# repeat history command
!number
press ctrl-r 提示符改变,显示我们正在执行反向增量搜索。 搜索过程是”反向的”,因为我们按照从”现在”到过去 某个时间段的顺序来搜寻。 下一步,我们开始输入要查找的文本搜索返回我们需要的结果。 (enter to execute, ctrl-j to copy)
| command | function | | :------ | :----------------------------------- | | Ctrl-p | 移动到上一个历史条目 | | Ctrl-n | 移动到下一个历史条目 | | Alt-< | 移动到历史列表开头 | | Alt-> | 移动到历史列表结尾 | | Ctrl-r | 反向增量搜索 | | Alt-p | 反向搜索,非增量搜索 | | Alt-n | 向前搜索,非增量 | | Ctrl-o | 执行历史列表中的当前项,并移到下一个 |
结合 updatedb 命令(该命令一般自动 1 天/次)
indicate how a command name is interpreted
display a list of appropriate commands
find [搜索路径] [可选参数] [文件名](可加"")
:
user_name
按照所有者搜索inode_number
grep
[可选参数] '字符串' 文件名
:
-I
: 不区分大小写-v
: 排除指定字符串-r
: recursive on directory-l
: only print matched filename--exclude
Find FunctionalComponent
in files and open them all:
grep -lr FunctionalComponent src --exclude=\*.md | xargs code
Average load information
Report a snapshot of current processes
ps aux
top/htop:
atop:
Outputs a snapshot of system resource usage:
Process and Thread:
pidstat 1
mpstat -P ALL 1
Show /proc/cpuinfo
.
list active jobs
place a job in the background
place a job in the foreground
send a signal to a process
kill processes by name
shutdown or reboot the system
outputs a process list arranged in a tree-like pattern
draws a graph showing system load over time
screen -S screenName
screen -ls
screen -r
concatenate files
sort lines of text
report or omit repeated lines
print newline, word, and byte counts for each file
output the first/last part of a file
head -n 5 filename
tail -f filename
read from standard input and write to standard output and files
[me@linuxBox ~]$ ls /usr/bin | tee ls.txt | grep zip
bunzip2
bzip2
....
number lines
wrap each line to a specified length
a simple text formatter
prepare text for printing
format and print data
显示 shell 内部命令帮助,如 cd 命令(shell 内部命令)
显示大型帮助文档 - enter 进入 u 返回 p 上一节 n 下一节 q 退出
sudo add-apt-repository ppa:dawidd0811/neofetch
sudo apt-get update
sudo apt-get install neofetch
sudo apt-get install screenfetch
不可压缩目录
tar.gz/.tar.bz2:
tar [可选参数] 压缩文件(可指定压缩路径) [-c 解压缩路径]源文件/源目录
7z x manager.7z -r -o /home/xx
7z a -t7z -r manager.7z /home/manager/*
groupadd test
groupmod -n test2 test -g
groupdel test2
cat /etc/passwd | awk -F [:] ‘{print $4}’
\ |sort|uniq | getent group |awk -F [:] ‘{print $1}’
useradd [options] LOGIN
Options:
useradd -s bash -m testUser
passwd testUser # modify `/etc/passwd`, then add to `/etc/sudoers`
adduser
is a perl script which uses useradd
binary in back-end,
adduser
is more user friendly and interactive.
usermod -d /home/test -G test2 test
gpasswd -a test test2 将用户 test 加入到 test2 组(附设组)
gpasswd -d test test2 将用户 test 从 test2 组中移出
usermod -aG sudo <username>
userdel test -r 同时删除用户登录目录(/home/xxx)
w/who 查看当前登录的所有用户
whoami 查看当前登录用户名
finger apacheUser 查看单个用户信息
id <username>
查看分区 ACL 权限是否开启 dumpe2fs -h 设备分区名
临时开启分区 ACL 权限 mount -o remount,acl 设备分区名
永久开启分区 ACL 权限 /etc/fstab
setfacl -m (d:默认权限) u/g:用户名/组名:权限(rwx) 文件名
getfacl 文件名——查看文件 ACL 权限
/etc/sudoers.tmp
可执行程序/目录+普通用户临时获得 root 权限 (rws):
主分区(primary)与延伸分区(extended) 延伸分区可以继续划分成逻辑分区(logical)
mount [-t 文件系统][-o 特殊选项] 设备文件名 挂载点(挂载目录/media /misc /mnt)
umount 设备文件名/挂载点
fdisk –l
sudo debugfs /dev/sda9
> debugfs: lsdel
分区表类型 MBR
n p e l 新 主 逻辑 扩展 分区 w 激活
分区表类型 MBR/GPT
read
+ write
: 4 context switch, 4 data copy (2 DMA, 2 CPU).mmap
+ write
: 4 context switch, 3 data copy (2 DMA, 1 CPU).sendfile
: 2 context switch, 3 data copy (2 DMA, 1 CPU).sendfile
: 2 context switch, 2 data copy (1 DMA, 1 SG-DMA).异步 I/O
+ 直接 I/O
,
传输小文件使用 Zero Copy.location /video/ {
sendfile on;
aio on;
directio 1024m;
}
#!/bin/bash
# Simple print cpu topology
# numactl --hardware
# ls /sys/devices/system/node/node0
# lscpu
function get_nr_processor()
{
grep '^processor' /proc/cpuinfo | wc -l
}
function get_nr_socket()
{
grep 'physical id' /proc/cpuinfo | awk -F: '{
print $2 | "sort -un"}' | wc -l
}
function get_nr_siblings()
{
grep 'siblings' /proc/cpuinfo | awk -F: '{
print $2 | "sort -un"}'
}
function get_nr_cores_of_socket()
{
grep 'cpu cores' /proc/cpuinfo | awk -F: '{
print $2 | "sort -un"}'
}
echo '===== CPU Topology Table ====='
echo
echo '+--------------+---------+-----------+'
echo '| Processor ID | Core ID | Socket ID |'
echo '+--------------+---------+-----------+'
while read line; do
if [ -z "$line" ]; then
printf '| %-12s | %-7s | %-9s |\n' $p_id $c_id $s_id
echo '+--------------+---------+-----------+'
continue
fi
if echo "$line" | grep -q "^processor"; then
p_id=`echo "$line" | awk -F: '{print $2}' | tr -d ' '`
fi
if echo "$line" | grep -q "^core id"; then
c_id=`echo "$line" | awk -F: '{print $2}' | tr -d ' '`
fi
if echo "$line" | grep -q "^physical id"; then
s_id=`echo "$line" | awk -F: '{print $2}' | tr -d ' '`
fi
done < /proc/cpuinfo
echo
awk -F: '{
if ($1 ~ /processor/) {
gsub(/ /,"",$2);
p_id=$2;
} else if ($1 ~ /physical id/){
gsub(/ /,"",$2);
s_id=$2;
arr[s_id]=arr[s_id] " " p_id
}
}
END{
for (i in arr)
printf "Socket %s:%s\n", i, arr[i];
}' /proc/cpuinfo
echo
echo '===== CPU Info Summary ====='
echo
nr_processor=`get_nr_processor`
echo "Logical processors: $nr_processor"
nr_socket=`get_nr_socket`
echo "Physical socket: $nr_socket"
nr_siblings=`get_nr_siblings`
echo "Siblings in one socket: $nr_siblings"
nr_cores=`get_nr_cores_of_socket`
echo "Cores in one socket: $nr_cores"
let nr_cores*=nr_socket
echo "Cores in total: $nr_cores"
if [ "$nr_cores" = "$nr_processor" ]; then
echo "Hyper-Threading: off"
else
echo "Hyper-Threading: on"
fi
echo
echo '===== END ====='
xrandr -s 1920x1800 # set resolution
sudo apt-get install read-edid
sudo get-edid | parse-edid
synclient TouchpadOff=0
安装和卸载时同时存在依赖性(包依赖、库依赖)
rpm 查询:
rpm 校验(查看 Cracker 信息):
源配置文件:/etc/yum.repos.d
cd /etc/yum.repos.d
mv CentOS-Base.repo CentOS-Base.repo.bk
wget http://mirrors.163.com/.help/CentOS7-Base-163.repo
yum makecache
指定位置:
(如上述脚本出错,执行 make clean)
make install
e.g apache /var/www/html/index.html /usr/local/apache/htdocs/index.html
/usr/share/applications
gnome-session-properties
or gnome-tweaks
update-alternatives
: maintain symbolic links determining default commands.
sudo update-alternatives --get-selections
sudo update-alternatives --install /usr/bin/x-terminal-emulator
\ x-terminal-emulator /opt/Hyper/hyper 50
sudo update-alternatives --config x-terminal-emulator
# Add key
sudo apt-add-repository ppa:user/repo
sudo apt update
# Delete key via last 8 bits
sudo apt-key list
sudo apt-key del 73C62A18
sudo apt update
wget -r -p -np -k -P ~/tmp/ http://java-er.com
CertBot for SSL certificates.
yum install python-setuptools && easy_install pip
pip install shadowsocks
echo "nohup sslocal -c /etc/shadowsocks.json /dev/null 2>&1 &" /etc/rc.local
nohup ssserver -c /etc/shadowsocks.json -d start /dev/null 2>&1 &
| 用途 | net-tool(被淘汰) | iproute2 | | :------------- | :--------------- | :--------------- | | 地址和链路配置 | ifconfig | ip addr, ip link | | 路由表 | route | ip route | | 邻居 | arp | ip neigh | | VLAN | vconfig | ip link | | 隧道 | iptunnel | ip tunnel | | 组播 | ipmaddr | ip maddr | | 统计 | netstat | ss |
ip link show
ip address show
ip route show
# add commands to /etc/init.d/local.sh
rm -fr /etc/udev/rules.d/70-persistent-net.rules
# start up network adapter
ip link set eth0 up
# add/delete static ip
ip address add 192.168.1.1/24 dev eth0
ip address del 192.168.1.1/24 dev eth0
# add/delete static route
ip route add 192.168.1.0/24 dev eth0
ip route del 192.168.1.0/24 dev eth0
ip route add default via 192.168.0.196
# watch packets
watch -n 1 "ifconfig eth0"
watch -n 1 "ifconfig eth1"
watch -n 1 "ifconfig eth2"
ufw status
ufw enable
ufw allow ssh
ufw allow http
ufw allow https
arp -a
显示地址解析协议 (IP 地址—网卡地址):
netstat -an
查看本机启用的端口:
nslookup domain_name
查看 DNS 解析器:
/etc/network/interfaces
主机名:
ping -c ip/domain
探测网络状况
telnet [ip/domain] [端口]
远程管理与端口探测命令
traceroute [-n IP] domain
路由跟踪命令traceroute -n -I -T -p
路由扫描nftables 命令行工具:nft
fping -a -u -g -f [target]
批量扫描主机地址
hping -p -S -a
可伪造 IP 地址
路由扫描
批量主机服务扫描:
批量主机服务扫描:
exec 1>>output.log exec 2>>error.log
systemctl enable local
in /etc/init.d/local
#!/bin/bash
### BEGIN INIT INFO
# Provides: local
# Required-Start: $all
# Required-Stop:
# Default-Start: 3 4 5
# Default-Stop:
# Short-Description: Personal start script
sslocal -c shadowsocks.json -d start
内存控制
sysctl vm [-options] CONFIG
swapoff
/etc/crontab
crontab -l(list)
crontab -e(establish)
jobs —— 所有作业
atq —— 延时作业队列
at -M(不使用邮件发送运行结果) -f filename deltaTime
atrm 作业号/名
bg/fg 作业号/名
nohup 脚本 & —— 脱离控制台并后台运行脚本
19 ~ -20 (-20 优先级最高)
命令间插入符
e.g ls && echo yes >> .log || echo no >> .log
ldd ./lib.sio
nm -Ca ./lib.so
chart.gp
#!/usr/bin/env gnuplot
set term wxt enhanced
set xtics
set view
set multiplot
set size
set origin
fit
plot 'data.dat' using 1:2, 'data.dat' using 1:3
#!/usr/bin/gnuplot -c
set terminal png enhanced
set output ARG1.".png"
set style data linespoints
show timestamp
set title ARG1
set xlabel "time (seconds)"
set ylabel "Segments (cwnd, ssthresh)"
plot ARG1 using 1:7 title "snd_cwnd", \
ARG1 using 1:($8>=2147483647 ? 0 : $8) title "snd_ssthresh"
date
change ntp (Network Time Protocol) time
sudo apt-get install ntpdate
sudo iptables -A OUTPUT -p udp --dport 123 -j ACCEPT
sudo iptables -A INPUT -p udp --sport 123 -j ACCEPT
sudo ntpdate time.windows.com
sudo hwclock --localtime --systohc
use local time (not UTC time)
sudo timedatectl set-local-rtc 1
>
文件名/输出设备名 覆盖标准输出重定向>>
文件名/输出设备名 追加标准输出重定向>/>> 文件 2>&1 &>/&>>文件
覆盖/追加正确输出与错误输出同时重定向</<<
文件名/输入设备名 覆盖/追加标准输入重定向command << END
...
END
command << EOF
...
EOF
#!/bin/bash
gnuplot -persist <<EOF
set data style linespoints
show timestamp
set title "$1"
set xlabel "time (seconds)"
set ylabel "Segments (cwnd, ssthresh)"
plot "$1" using 1:7 title "snd_cwnd", \\
"$1" using 1:(\$8>=2147483647 ? 0 : \$8) title "snd_ssthresh"
EOF
=
: 左右两端不可有空格' '
: 完全标准字符串" "
: 格式化字符串$*
/$@
: argv[1], ..., argv[n]
$0/$1/../$n
: argv[0], ..., argv[n]
$#
: argc$?
: exit code of last commandif [ "$?" -ne "0" ];then
echo "sorry, command execution failed!"
fi
每次 shift 命令执行的时候,变量 1 中,变量 2 中. 变量 $# 的值也会相应的减 1
#!/bin/bash
# posit-param2: script to display all arguments
count=1
while [[ $# -gt 0 ]]; do
echo "Argument $count = $1"
count=$((count + 1))
shift
done
usage () {
echo "$PROGNAME: usage: $PROGNAME [-f file | -i]"
return
}
# process command line options
interactive=
filename=
while [[ -n $1 ]]; do
case $1 in
-f | --file) shift
filename=$1
;;
-i | --interactive) interactive=1
;;
-h | --help) usage
exit
;;
*) usage >&2
exit 1
;;
esac
shift
done
$(())
or $[]
: arithmetic expansion一般地, 将数值运算用 (())
[[]]
或 $(())
括起, 可以确保变量不会被识别为 string
read x
read y
echo $((x + y))
echo $((a < b ? a : b))
if ((a > b))
then
echo "a > b"
fi
if [[ a -gt b ]]
then
echo "a > b"
fi
if [ "$a" -gt "$b" ]
then
echo "a > b"
fi
[[ xxx ]]
: condition(( xxx ))
: arithmetic condition| operator | function |
| :-------------------- | :------------------------------------------------ |
| ! EXPRESSION | The EXPRESSION is false |
| -n STRING | The length of STRING is greater than zero |
| -z STRING | The length of STRING is zero (ie it is empty) |
| STRING1 == STRING2 | STRING1 is equal to STRING2 |
| STRING1 != STRING2 | STRING1 is not equal to STRING2 |
| STRING1 > STRING2 | STRING1 sorts after STRING2 |
| STRING1 < STRING2 | STRING1 sorts before STRING2 |
| INTEGER1 -eq INTEGER2 | INTEGER1 is numerically equal to INTEGER2 |
| INTEGER1 -gt INTEGER2 | INTEGER1 is numerically greater than INTEGER2 |
| INTEGER1 -lt INTEGER2 | INTEGER1 is numerically less than INTEGER2 |
| -d FILE | FILE exists and is a directory |
| -e FILE | FILE exists |
| -r FILE | FILE exists and the read permission is granted |
| -s FILE | FILE exists and it's size is greater than zero |
| -w FILE | FILE exists and the write permission is granted |
| -x FILE | FILE exists and the execute permission is granted |
| AND -a &&
| |
| OR -o \|\|
| |
| NOT ! !
| |
echo a{A{1,2},B{3,4}}b
aA1b aA2b aB3b aB4b
${}
: string expansion
${parameter:-word}
: 若 parameter 没有设置(例如,不存在)或者为空,展开结果是 word 的值。
若 parameter 不为空,则展开结果是 parameter 的值${parameter:+word}
: 若 parameter 没有设置或为空,展开结果为空。
若 parameter 不为空, 展开结果是 word 的值会替换掉 parameter 的值${parameter:=word}
: 若 parameter 没有设置或为空,展开结果是 word 的值。
另外,word 的值会赋值给 parameter。
若 parameter 不为空,展开结果是 parameter 的值${parameter:?word}
: 若 parameter 没有设置或为空,这种展开导致脚本带有错误退出,
并且 word 的内容会发送到标准错误。
若 parameter 不为空, 展开结果是 parameter 的值${!prefix*}
${!prefix@}
: 这种展开会返回以 prefix 开头的已有变量名${#parameter}
: 展开成由 parameter 所包含的字符串的长度${parameter:offset}
${parameter:offset:length}
: 提取一部分字符${parameter,,}
把 parameter 的值全部展开成小写字母${parameter,}
仅仅把 parameter 的第一个字符展开成小写字母${parameter^^}
把 parameter 的值全部转换成大写字母${parameter^}
仅仅把 parameter 的第一个字符转换成大写字母${parameter#pattern}
${parameter##pattern}
,
${parameter%pattern}
${parameter%%pattern}
: 从 parameter 所包含的字符串中清除开头/末尾一部分文本${parameter/pattern/string}
, ${parameter//pattern/string}
,
${parameter/#pattern/string}
, ${parameter/%pattern/string}
: replacefoo=file.txt.zip
echo ${foo#*.}
txt.zip
echo ${foo##*.}
zip
foo=file.txt.zip
echo ${foo%.*}
file.txt
echo ${foo%%.*}
file
foo=JPG.JPG
echo ${foo/JPG/jpg}
jpg.JPG
echo ${foo//JPG/jpg}
jpg.jpg
echo ${foo/#JPG/jpg}
jpg.JPG
echo ${foo/%JPG/jpg}
JPG.jpg
if [[ 条件判断式 ]] ; then
程序
fi
if [[ 条件判断式 ]]
then
程序
else
程序
fi
if [[ 条件判断式1 ]]
then
程序1
elif [[ 条件判断式2 ]]
then
程序2
……
else
程序n
fi
case $变量名 in
“值1”)
程序
;;
“值2”)
程序
;;
*)
程序
;;
esac
| case pattern | function |
| :------------- | :------------------------------------ |
| a)
| word equals "a" |
| [[:alpha:]])
| word is a single alphabetic character |
| ???)
| word is exactly three characters long |
| \*.txt)
| word ends with the characters “.txt” |
| *)
| any value of word |
#!/bin/bash
# case-menu: a menu driven system information program
clear
echo "
Please Select:
1. Display System Information
2. Display Disk Space
3. Display Home Space Utilization
0. Quit
"
read -p "Enter selection [0-3] > "
case $REPLY in
0) echo "Program terminated."
exit
;;
1) echo "Hostname: $HOSTNAME"
uptime
;;
2) df -h
;;
3) if [[ $(id -u) -eq 0 ]]; then
echo "Home Space Utilization (All Users)"
du -sh /home/*
else
echo "Home Space Utilization ($USER)"
du -sh $HOME
fi
;;
*) echo "Invalid entry" >&2
exit 1
;;
esac
or case pattern
#!/bin/bash
# case-menu: a menu driven system information program
clear
echo "
Please Select:
A. Display System Information
B. Display Disk Space
C. Display Home Space Utilization
Q. Quit
"
read -p "Enter selection [A, B, C or Q] > "
case $REPLY in
q|Q) echo "Program terminated."
exit
;;
a|A) echo "Hostname: $HOSTNAME"
uptime
;;
b|B) df -h
;;
c|C) if [[ $(id -u) -eq 0 ]]; then
echo "Home Space Utilization (All Users)"
du -sh /home/*
else
echo "Home Space Utilization ($USER)"
du -sh $HOME
fi
;;
*) echo "Invalid entry" >&2
exit 1
;;
esac
fall through case pattern (;;&
)
#!/bin/bash
# case4-2: test a character
read -n 1 -p "Type a character > "
echo
case $REPLY in
[[:upper:]]) echo "'$REPLY' is upper case." ;;&
[[:lower:]]) echo "'$REPLY' is lower case." ;;&
[[:alpha:]]) echo "'$REPLY' is alphabetic." ;;&
[[:digit:]]) echo "'$REPLY' is a digit." ;;&
[[:graph:]]) echo "'$REPLY' is a visible character." ;;&
[[:punct:]]) echo "'$REPLY' is a punctuation symbol." ;;&
[[:space:]]) echo "'$REPLY' is a whitespace character." ;;&
[[:xdigit:]]) echo "'$REPLY' is a hexadecimal digit." ;;&
esac
for 变量 in 值1 值2 值3 …… 值n
do
程序
done
$(seq 1 50) # 1 2 ... 50
{1..50} # 1 2 ... 50
{0..10..2} # 0 2 4 6 8 10
for (( 初始值;循环控制条件;变量变化 )); do
程序
done
while [[ 条件判断式 ]]
do
程序
done
until [[ 条件判断式 ]]
do
程序
done
(( expression1 ))
while (( expression2 )); do
commands
(( expression3 ))
done
#!/bin/bash
# while-menu: a menu driven system information program
DELAY=3 # Number of seconds to display results
while [[ $REPLY != 0 ]]; do
clear
cat <<- _EOF_
Please Select:
1. Display System Information
2. Display Disk Space
3. Display Home Space Utilization
0. Quit
_EOF_
read -p "Enter selection [0-3] > "
if [[ $REPLY =~ ^[0-3]$ ]]; then
if [[ $REPLY == 1 ]]; then
echo "Hostname: $HOSTNAME"
uptime
sleep $DELAY
fi
if [[ $REPLY == 2 ]]; then
df -h
sleep $DELAY
fi
if [[ $REPLY == 3 ]]; then
if [[ $(id -u) -eq 0 ]]; then
echo "Home Space Utilization (All Users)"
du -sh /home/*
else
echo "Home Space Utilization ($USER)"
du -sh $HOME
fi
sleep $DELAY
fi
else
echo "Invalid entry."
sleep $DELAY
fi
done
echo "Program terminated."
#!/bin/bash
# while-read: read lines from a file
while read dist version release; do
printf "Dist: %s\tVersion: %s\tReleased: %s\n" \
$dist \
$version \
$release
done < dist.txt
while : ; do
actions
[[ current_time <= $cutoff ]] || break
done
#!/bin/bash
# read-validate: validate input
invalid_input () {
echo "Invalid input '$REPLY'" >&2
exit 1
}
read -p "Enter a single item > "
# input is empty (invalid)
[[ -z $REPLY ]] && invalid_input
# input is multiple items (invalid)
(( $(echo $REPLY | wc -w) > 1 )) && invalid_input
# is input a valid filename?
if [[ $REPLY =~ ^[-[:alnum:]\._]+$ ]]; then
echo "'$REPLY' is a valid filename."
if [[ -e $REPLY ]]; then
echo "And file '$REPLY' exists."
else
echo "However, file '$REPLY' does not exist."
fi
# is input a floating point number?
if [[ $REPLY =~ ^-?[[:digit:]]*\.[[:digit:]]+$ ]]; then
echo "'$REPLY' is a floating point number."
else
echo "'$REPLY' is not a floating point number."
fi
# is input an integer?
if [[ $REPLY =~ ^-?[[:digit:]]+$ ]]; then
echo "'$REPLY' is an integer."
else
echo "'$REPLY' is not an integer."
fi
else
echo "The string '$REPLY' is not a valid filename."
fi
#!/bin/bash
# read-menu: a menu driven system information program
clear
echo "
Please Select:
1. Display System Information
2. Display Disk Space
3. Display Home Space Utilization
0. Quit
"
read -p "Enter selection [0-3] > "
if [[ $REPLY =~ ^[0-3]$ ]]; then
if [[ $REPLY == 0 ]]; then
echo "Program terminated."
exit
fi
if [[ $REPLY == 1 ]]; then
echo "Hostname: $HOSTNAME"
uptime
exit
fi
if [[ $REPLY == 2 ]]; then
df -h
exit
fi
if [[ $REPLY == 3 ]]; then
if [[ $(id -u) -eq 0 ]]; then
echo "Home Space Utilization (All Users)"
du -sh /home/*
else
echo "Home Space Utilization ($USER)"
du -sh $HOME
fi
exit
fi
else
echo "Invalid entry." >&2
exit 1
fi
# interactive mode
if [[ -n $interactive ]]; then
while true; do
read -p "Enter name of output file: " filename
if [[ -e $filename ]]; then
read -p "'$filename' exists. Overwrite? [y/n/q] > "
case $REPLY in
Y|y) break
;;
Q|q) echo "Program terminated."
exit
;;
*) continue
;;
esac
elif [[ -z $filename ]]; then
continue
else
break
fi
done
fi
-x
option
#!/bin/bash -x
# trouble: script to demonstrate common errors
number=1
if [ $number = 1 ]; then
echo "Number is equal to 1."
else
echo "Number is not equal to 1."
fi
#!/bin/bash
# trouble: script to demonstrate common errors
number=1
echo "number=$number" # DEBUG
set -x # Turn on tracing
if [ $number = 1 ]; then
echo "Number is equal to 1."
else
echo "Number is not equal to 1."
fi
set +x # Turn off tracing
cat /etc/shells
bash strict mode
[[ ]]
cp -r "$src_dir" "$dest_dir"
$()
获取表达式的值${arr[@]}
进行列表循环#!/usr/bin/env bash
# 设置命令回显
set -x
# 遇到未声明的变量则报错停止
set -u
# 遇到执行错误则停止
set -e
# 管道命令其中一步失败则中止
set -o pipefail
if (( $EUID != 0 )); then
echo "Please run as root!"
exit
fi
# run as root directly
sudo chown root <filename>
sudo chmod +s <filename>
#!/bin/sh
if [[ ${#@} -ne 0 ]] && [[ "${@#"--help"}" = "" ]]; then
printf -- '...help...\n';
exit 0;
fi;
#!/bin/sh
if [[ ${#@} -ne 0 ]] && [[ "${@#"--silent"}" = "" ]]; then
stty -echo;
fi;
# ...
# before point of intended output:
stty +echo && printf -- 'intended output\n';
# silence it again till end of script
stty -echo;
# ...
stty +echo;
exit 0;
#!/bin/sh
_=$(command -v docker);
if [[ "$?" != "0" ]]; then
printf -- 'You don\'t seem to have Docker installed.\n';
printf -- 'Get it: https://www.docker.com/community-edition\n';
printf -- 'Exiting with code 127...\n';
exit 127;
fi;
#!/bin/sh
CUR_DIR="$(dirname $0);"
printf -- 'moving application to /opt/app.jar';
mv "${CUR_DIR}/application.jar" /opt/app.jar;
#!/bin/sh
error_handle() {
stty echo;
}
if [[ ${#@} -ne 0 ]] && [[ "${@#"--silent"}" = "" ]]; then
stty -echo;
trap error_handle INT;
trap error_handle TERM;
trap error_handle KILL;
trap error_handle EXIT;
fi;
# ...
#!/bin/sh
printf -- 'Performing asynchronous action..';
./trigger-action;
DONE=0;
while [ $DONE -eq 0 ]; do
./async-checker;
if [ "$?" = "0" ]; then DONE=1; fi;
printf -- '.';
sleep 1;
done;
printf -- ' DONE!\n';
# Install zsh and powerline
sudo apt install zsh powerline powerline-status
# Install oh-my-zsh
sh -c "$(wget -O- https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
# Install zsh themes
git clone --depth=1 https://github.com/romkatv/powerlevel10k.git ${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}/themes/powerlevel10k
git clone --depth=1 https://github.com/sabertazimi/dragon-zsh-theme.git ${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}/themes/dragon
# Install zsh plugins
git clone https://github.com/zsh-users/zsh-autosuggestions ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-autosuggestions
git clone https://github.com/zsh-users/zsh-syntax-highlighting.git ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-syntax-highlighting
plugins=(
command-not-found fzf git git-prompt github
history lighthouse man node npm nvm pm2 vi-mode yarn
)
stty
命令对 TTY 设备进行配置.ssh
也是一种伪终端 PTY:
bash
and ssh client
.ssh server
, PTY Slave is bash
.update-alternatives
: maintain symbolic links determining default commands.
sudo update-alternatives --get-selections
sudo update-alternatives --install /usr/bin/x-terminal-emulator
\ x-terminal-emulator /opt/Hyper/hyper 50
sudo update-alternatives --config x-terminal-emulator
tmux ls
tmux new -s sessionID
tmux a -t sessionID # attach
tmux show -g >> current.tmux.conf # export configuration
? # 快捷键帮助列表
:new<CR> # 创建新的 Session,其中 : 是进入 Tmux 命令行的快捷键
s list sessions
$ rename the current session
d detach from the current session
c create a new window
, rename the current window
w list windows
% split horizontally
" split vertically
n change to the next window
p change to the previous window
0 to 9 select windows 0 through 9
% create a horizontal pane
" create a vertical pane
<space> # 切换 Pane 布局
h move to the left pane. *
j move to the pane below *
l move to the right pane *
k move to the pane above *
q show pane numbers
o toggle between panes
} swap with next pane
{ swap with previous pane
! break the pane out of the window
x kill the current pane
t # 显示一个时钟
C-a + [
to into scroll mode, q
to quit scroll modeset -g mouse on
for enabling mouse scrolling# C-b is not acceptable -- Vim uses it
set-option -g prefix C-a
bind-key C-a last-window
# Start numbering at 1
set -g base-index 1
# Allows for faster key repetition
set -s escape-time 0
# Set status bar
set -g status-bg black
set -g status-fg white
set -g status-left ""
set -g status-right "#[fg=green]#H"
# Enable scroll mouse
set -g mouse on
# Rather than constraining window size to the maximum size of any client
# connected to the *session*, constrain window size to the maximum size of any
# client connected to *that window*. Much more reasonable.
setw -g aggressive-resize on
# Allows us to use C-a a <command> to send commands to a TMUX session inside
# another TMUX session
bind-key a send-prefix
# Reload configuration
bind r source-file ~/.tmux.conf \; display-message "Config reloaded"
# Escape to enter copy mode, v to selection, y to yank, p to paste
bind Escape copy-mode
bind-key -T copy-mode-vi 'v' send -X begin-selection
bind-key -T copy-mode-vi 'y' send -X copy-selection-and-cancel
# bind-key -t vi-copy v begin-selection
# bind-key -t vi-copy y copy-pipe "reattach-to-user-namespace pbcopy"
unbind p
bind p pasteb
setw -g mode-keys vi # Vi
# Highlight active window
set-window-option -g window-status-current-bg red
top
dmesg | tail
iostat -xz 1
free -m
`sar -n DEV 1`
`sar -n TCP,ETCP 1`
perf list # events
perf stat <command>
perf stat -e <events> <command>
perf record -e <events> -a <command>
perf report
# https://www.yanxurui.cc/posts/tool/2017-10-07-use-ffmpeg-to-edit-video
ffmpeg -global_options -input_1_options -i input_1 -input_2_options -i input_2 \
-output_1_options output_1 ...
ffprobe input.mp4
ffmpeg -hide_banner -i input.mkv
MP4
: H264
Video + ACC
AudioWebM
: VP8
Video + Vorbis
AudioOGG
: Theora
Video + Vorbis
Audio# code decoder information
ffmpeg -codecs
# mkv to mp4
ffmpeg -i input.mkv -codec copy output.mp4
# compress
ffmpeg -i input.mkv -c copy -c:v libx264 -vf scale=-2:720 output.mkv
# make mkv with video and subtitle
ffmpeg -i input.avi -i input.srt \
-map 0:0 -map 0:1 -map 1:0 -c:v libx264 -c:a aac -c:s srt output.mkv
# flac to mp3
ffmpeg -i "Michael Jackson - Billie Jean.flac" \
-ab 320k "Michael Jackson - Billie Jean.mp3"
ffmpeg -i music_flac.flac \
-acodec libmp3lame \
-ar 44100 \
-ab 320k \
-ac 2 music_flac_mp3.mp3
# - acodec: Audio Coder Decoder 音频编码解码器
# - libmp3lame: MP3 解码器
# - ar: audio rate 音频采样率, 默认用原音频的采样率
# - ab: audio bit rate 音频比特率, 默认 128K
# - ac: audio channels 音频声道, 默认采用源音频的声道数
# mp4 to avi
ffmpeg -i video.mp4 \
-s 1920x1080 \
-pix_fmt yuv420p \
-vcodec libx264 \
-preset medium \
-profile:v high \
-level:v 4.1 \
-crf 23 \
-r 30 \
-acodec aac \
-ar 44100 \
-ac 2 \
-b:a 128k video_avi.avi
# - s: 缩放视频新尺寸 (size)
# - pix_fmt:pixel format, 设置视频颜色空间
# - vcodec: Video Coder Decoder, 视频编码解码器
# - preset: 编码器预设
# - profile:v: 编码器配置, 与压缩比有关. 实时通讯-baseline, 流媒体-main, 超清视频-high
# - level:v: 对编码器设置的具体规范和限制, 权衡压缩比和画质
# - crf: 设置码率控制模式, constant rate factor恒定速率因子模式, 范围 0~51, 数值越小, 画质越高
# - r:设置视频帧率
# - b:a: 音频比特率, 大多数网站限制音频比特率 128k, 129k
# audio only
ffmpeg -i cut.mp4 -vn output.mp3
ffmpeg -i video.mp4 -vn -acodec copy video_noVideo.m4a
# video only
ffmpeg -i video.mp4 -vcodec copy -an video_silent.mp4
# from to cutting
ffmpeg -i music.mp3 -ss 00:00:30 -to 00:02:00 -acodec copy music_cutout.mp3
ffmpeg -i in.mp4 -ss 00:01:00 -to 00:01:10 -c copy out.mp4
ffmpeg -ss 00:01:00 -i in.mp4 -to 00:01:10 -c copy -copyts out.mp4
# 30s duration cutting
ffmpeg -ss 00:02:00.0 -i input.mkv -t 30 -c copy output.mkv
ffmpeg -i input.mkv -ss 00:02:00.0 -t 30 -c copy output.mkv
ffmpeg -ss 00:01:30.0 -i input.mkv -ss 00:00:30.0 -t 30 output.mkv
# replace audio
ffmpeg -i input.mkv -i input.mp3 -map 0:v -map 1:a -c copy -shortest output.mp4
# merge audio and video
ffmpeg -i video_noVideo.m4a -i video_silent.mp4 -c copy video_merge.mp4
ffmpeg -i "concat:01.mp4|02.mp4|03.mp4" -c copy out.mp4
ffmpeg -i input.mkv -i output.aac \
-filter_complex "[0:a][1:a]amerge=inputs=2[a]" -map 0:v -map "[a]" \
-c:v copy -c:a aac -ac 2 -shortest output.mp4
# -vf -> -filter:v
ffmpeg -ss 00:30:14.435 -i input.mkv -vframes 1 out.png
ffmpeg -i input.mkv -vf fps=1/60 -strftime 1 out_%Y%m%d%H%M%S.jpg
ffmpeg -i video.mp4 -ss 7.5 -to 8.5 -s 640x320 -r 15 video_gif.gif
palette="/tmp/palette.png"
filters="fps=10,scale=-1:144:flags=lanczos"
ffmpeg -ss 30 -t 5 -i input.mp4 -vf "$filters,palettegen" -y $palette
ffmpeg -ss 30 -t 5 -i input.mp4 -i $palette \
-filter_complex "$filters [x]; [x][1:v] paletteuse" -y output.gif
ffmpeg -i input.mkv -vf subtitles=input.srt output.mp4
ffmpeg -i input.mkv -vf ass=input.ass output.mp4
ffmpeg -i input.mkv -i input.png \
-filter_complex "overlay=W-w-5:5" -c copy -c:v libx264 output.mkv
# windows
ffmpeg -f gdigrab -i desktop rec.mp4
# linux
sudo ffmpeg -f fbdev -framerate 10 -i /dev/fb0 rec.mp4
ffmpeg -re i rec.mp4 按照网站要求编码 -f flv "你的 RTMP 地址/你的直播码"
/etc/nginx/sites-available
: sites confignginx -t # check config syntax
泛域名路径分离: xxx.test.dev
-> /usr/local/html/xxx
server {
listen 80;
server_name ~^([\w-]+)\.test\.dev$;
root /usr/local/html/$1;
}
server {
# SSL configuration
#
# listen 443 ssl default_server;
# listen [::]:443 ssl default_server;
#
root /var/www/html/;
# Add index.php to the list if you are using PHP
index index.html index.htm index.nginx-debian.html;
server_name example.tld www.example.tld;
# Cache static assets
location ~* \.(?:jpg|jpeg|gif|png|ico|svg)$ {
expires 7d;
add_header Cache-Control "public";
}
location ^~ /assets/ {
gzip_static on;
expires 12h;
add_header Cache-Control "public";
}
# Cache css and js bundle
location ~* \.(?:css|js)$ {
add_header Cache-Control "no-cache, public, must-revalidate, proxy-revalidate";
}
location / {
include /etc/nginx/mime.types;
try_files $uri $uri/ /index.html;
# try_files $uri $uri/ =404;
# proxy_http_version 1.1;
# proxy_cache_bypass $http_upgrade;
# proxy_set_header Upgrade $http_upgrade;
# proxy_set_header Connection 'upgrade';
# proxy_set_header Host $host;
# proxy_set_header X-Real-IP $remote_addr;
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# proxy_set_header X-Forwarded-Proto $scheme;
# proxy_pass http://localhost:3000;
}
}
# PID Namespace
unshare --fork --pid --mount-proc /bin/bash
ps -aux
# Mount Namespace
unshare --fork --mount /bin/bash
mkdir /tmp/mnt
mount -t tmpfs -o size=1m tmpfs /tmp/mnt
df -h |grep mnt
# User Namespace
PS1='\u@container#' unshare --user -r /bin/bash
# UTS Namespace (isolated hostname)
unshare --fork --uts /bin/bash
hostname -b container
# IPC Namespace
unshare --fork --ipc /bin/bash
ipcmk -Q
ipcs -q
# Net Namespace
unshare --fork --net /bin/bash
ip addr
netstat -ntlp
Cgroup (Linux Control Group): limit process group resources usage, including CPU, Memory, Disk I/O, Network Bandwidth etc.
List cgroup
mount -t cgroup
ls -l /sys/fs/cgroup/
Create cgroup
mkdir /sys/fs/cgroup/cpu/loop
ls -l /sys/fs/cgroup/cpu/loop
cat /sys/fs/cgroup/cpu/loop/cpu.cfs_period_us # 100000us
cat /sys/fs/cgroup/cpu/loop/cpu.cfs_quota_us # -1 (no limit)
Resource control via cgroup
# limit cpu usage to 50%
echo 50000 >/sys/fs/cgroup/cpu/loop/cpu.cfs_quota_us
# add pid to `loop` cgroup
echo 21497 >/sys/fs/cgroup/cpu/loop/tasks
sudo apt-get update
sudo apt-get install \
apt-transport-https \
ca-certificates \
curl \
gnupg \
lsb-release
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io
curl -fsSL https://get.docker.com -o get-docker.sh
sudo DRY_RUN=1 sh get-docker.sh
sudo systemctl status docker
sudo usermod -aG docker $USER
docker container stop $(docker container ls -aq)
docker system prune -a --volumes
sudo apt purge docker-ce docker-ce-cli containerd.io
sudo apt autoremove
sudo rm -rf /var/lib/docker
sudo rm -rf /var/lib/containerd
docker build . -t image-name
# use Dockerfile at the root of the repository
docker build <github-repo-url> -t image-name
# docker run -dp <host-port>:<container-port> [docker-image]
docker run -d -p 80:80 --name app-name docker/getting-started
docker run -d -p 80:80/tcp -p 80:80/udp --name app-name docker/getting-started