linux-tips-daily

Tips

Here are some tips that are useful in our daily life.

remove ‘du du’ sound when tap keyboard

1
$ sudo rmmod pcspkr

linux mount file

mount files from windows by samba

1
2
3
4
5
6
7
8
9
10
11
12
13
# Centos7
$ yum install -y cifs-utils
$ sudo mount -t cifs //serverip/share /media/share -o user,sync,user=xxx,password=pxx,uid=1000,gid=1000,file_mode=0600,dir_mode=0700,noperm

# error cases
# case: wrong password (special characters that can not pass through command line)
# case: wrong source directory(caused by wrong spell or format is not correct)
# case: access control issue.
# case: ubuntu iptables
# case: proxy(router)firewall

# case: china character show incorrectly. export LC_ALL=zh_CN.utf8
# before you set, make sure to run $ locale -a to see all language supported.

mount iso file

1
2
$ mount -o loop disk.iso  /mnt/disk
$ umount /mnt/disk

mount a raw file

1
2
3
4
5
6
7
8
9
10
11
12
# check disk type raw or qcow2
$ qemu-img info disk.img
...
file format: raw
...

# get file system type
$ blkid disk.img

# mount it
$ mount -t xfs disk.img /mnt/disk
$ umount /mnt/disk

mount a qcow2 file

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# use a free nbd device
$ qemu-nbd -c /dev/nbd100 disk.qcow2

# mount the first partition or second ..
$ fdisk /dev/nbd100 -l
Disk label type: dos
Disk identifier: 0x000eb26e

Device Boot Start End Blocks Id System
/dev/nbd100p1 * 2048 616447 307200 83 Linux
/dev/nbd100p2 616448 1011460095 505421824 8e Linux LVM

$ mount /dev/nbd100p1 /mnt/disk

# =====fix the partition table=========================
# if you see below error
mount: special device /dev/nbd100p1 does not exist
# if kpartx is not working, try partx -a /dev/nbd100
$ kpartx -a /dev/nbd100
# =====fix the partition table=========================

$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
...
nbd100 43:100 0 500G 0 disk
├─nbd100p1 253:0 0 300M 0 part
└─nbd100p2 253:1 0 482G 0 part
├─centos_dev-root 253:2 0 100G 0 lvm
├─centos_dev-home 253:3 0 300G 0 lvm
├─centos_dev-swap 253:4 0 32G 0 lvm
└─centos_dev-var 253:5 0 50G 0 lvm

# mount this
$ mount /dev/centos_dev/root /mnt/disk
$ umount /mnt/disk
$ qemu-nbd -d /dev/nbd100

# =========================another way: guestmount===================
# NOTE: this will start a micro vm(qemu-kvm)
$ guestmount -a disk.qcow2 -i --ro /mnt/disk
$ guestumount /mnt/disk
# =========================another way: guestmount===================

lsattr and chattr

1
2
3
4
5
6
7
8
9
10
11
12
a: append only; 系统只允许在这个文件之后追加数据,不允许任何进程覆盖或截断这个文件。如果目录具有这个属性,系统将只允许在这个目录下建立和修改文件,而不允许删除任何文件。
c: compressed; 系统以透明的方式压缩这个文件。从这个文件读取时,返回的是解压之后的数据;而向这个文件中写入数据时,数据首先被压缩之后才写入磁盘。
d: no dump; 在进行文件系统备份时,dump程序将忽略这个文件。
i: immutable; 系统不允许对这个文件进行任何的修改。如果目录具有这个属性,那么任何的进程只能修改目录之下的文件,不允许建立和删除文件。
j: data journalizing; 如果一个文件设置了该属性,那么它所有的数据在写入文件本身之前,写入到ext3文件系统日志中,如果该文件系统挂载的时候使用了”data=ordered” 或”data=writeback”选项。当文件系统采用”data=journal”选项挂载时,所有文件数据已经记录日志,因此这个属性不起作用。仅仅超级用户或者拥有CAP_SYS_RESOURCE能力的进程可以设置和删除该属性。
s: secure deletion; 让系统在删除这个文件时,使用0填充文件所在的区域。
t: no tail-merging; 和其他文件合并时,该文件的末尾不会有部分块碎片(为支持尾部合并的文件系统使用)。
u: undeletable; 当一个应用程序请求删除这个文件,系统会保留其数据块以便以后能够恢复删除这个文件。
A: no atime updates; 告诉系统不要修改对这个文件的最后访问时间
D: synchronous directory updates; 任何改变将同步到磁盘;这等价于mount命令中的dirsync选项:
S: synchronous updates; 一旦应用程序对这个文件执行了写操作,使系统立刻把修改的结果写到磁盘。
T: top of directory hierarchy; 如果一个目录设置了该属性,它将被视为目录结构的顶极目录

config nameserver

There are two ways to configure it, one shot or permanently

1
2
3
4
5
6
7
# one shot
edit /etc/resolv.conf directly
# Note: this file is dynamically created, if networking service restart or host reboots, its content will be overwritten

# you can also change the file 'attr' make it readonly to prevent rewriting
$ chattr +i /etc/resolve.conf
$ lsattr /etc/resolve.conf

config static address

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# Centos7
# edit /etc/sysconfig/network-scripts/ifcfg-eth0
HWADDR=52:54:00:12:34:56
TYPE=Ethernet
BOOTPROTO=none
IPADDR=172.17.0.2
NETMASK=255.255.255.0
GATEWAY=172.17.0.1
DNS1=172.17.0.1
DNS2=8.8.8.8
DEFROUTE=yes
IPV6INIT=no
NAME=eth0
DEVICE=eth0
ONBOOT=yes
UUID=fd2fe799-fd63-4de9-b8db-773eecf9f8e0

grep/egrep/rgrep/zgrep options

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# egrep: support basic regular pattern and extended pattern like + etc
# grep : grep -E to use extended pattern and grep -v to search recursively
# rgrep: recursively search
# zgrep: like grep but support search .gz without extract content

-a treat binary as text
-C | A | B num show NUM lines before/after/center the matching line
-n show line number
-l list file name that contains the content
-H list file name and line number for matching
-v list lines tht NOT matches
-r recursively search subdir as well without follow symbolic links
-R recursively search subdir as well with following symbolic links
-o Print only the matched (non-empty) parts of a matching line, with each such part on a separate output line, print matched part not the whole line!

-E extended pattern

# better to add alias to your bashrc
# alias grep='grep -anH'

$ grep -anH -C "home" text.txt
$ grep -anH -C "home" *.txt

# use pattern, must quote 'ho+' to prevent the shell from erroneously replacing that
# pattern with a list of filenames that match the pattern
$ grep -anHE -C "ho*" *.txt

$ grep "home" *.txt # only *.txt file at current level
$ grep -r "home" *.txt # all .txt files and subdir
$ grep -v "Home" text.txt # list unmatched lines!!!

# grep chinese character
$ grep -P '[\p{Han}]' *.txt

# show lines with ipv4 address
$ grep -E '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' ip.txt

# show matched ipv4 address only
$ grep -o -E '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' ip.txt

# grep for multiple patterns
$ grep -E 'pattern1|pattern2' *.py
$ egrep 'pattern1|pattern2' *.py

show current runlevel

1
2
3
# show current runlevel
$ runlevel
2

manage service

service management

1
2
3
4
5
6
# lists the state of services controlled by System V and upstart
$ service --status-all
output format:
+ running
- stopped
? unknown(managed by upstart)

write a system V service

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
/etc/init.d/dhcp
----service name ==dhcp

# run it at init by create symbol link to it on each runlevel
# like /etc/rc3.d/S20dhcp (will boot dhcp when starts on runlevel 3)


# dhcp file

#!/bin/sh
# dhcp
# Start/Stop dhcp
#
### BEGIN INIT INFO
# Provides: dhcp
# Required-Start: $network $local_fs
# Required-Stop: $network $local_fs
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: dhcp Server
### END INIT INFO

start() {
...
}

stop() {
...
}

#
# main
#
case "$1" in
start)
start
;;
stop)
stop
;;
status)
if [ -n "$(pidof -xs "${PROG}")" ] ; then
echo "${PROG_TAG} is running"
exit 0
else
echo "${PROG_TAG} is not running"
# Returning 3 like everyone else.
exit 3
fi
;;
restart)
stop
start
;;
clear)
stop
clear
;;
*)
echo $"Usage: $0 {start|stop|restart|status}"
exit 3
esac

write a upstart service(ubuntu18)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58

/etc/init/dhcp.conf
---service name==dhcp
# !!!plain txt, but with upstart format!!!

# dhcp.conf file
# UpStart service config
# details in http://upstart.ubuntu.com/cookbook/
description "dhcp server"

# Runlevel
start on runlevel [345]
stop on runlevel [!345]

# Umask
umask 0007

# Core limit
limit core unlimited unlimited

# Expect the process executed to call fork
# fork: exactly once.
# daemon: exactly twice.
expect fork

# Respawn the job up to 3 times within a 5 second period.
# If the job exceeds these values, it will be stopped and
# marked as failed.
respawn
respawn limit 3 5

# Redirect console to /var/log/upstart/*.log
console log

# Hooks
pre-start script
echo "# Starting at $(date -u +'%Y-%m-%dT%H:%M:%S.%NZ')"
# Create run time file directory
mkdir -m 0755 -p /var/run/dhcp
end script

post-start script
echo "# Started at $(date -u +'%Y-%m-%dT%H:%M:%S.%NZ')"
end script

pre-stop script
echo "# Pre-Stopping at $(date -u +'%Y-%m-%dT%H:%M:%S.%NZ')"
end script

post-stop script
echo "# Stopped at $(date -u +'%Y-%m-%dT%H:%M:%S.%NZ')"
end script

# Start the process
exec start-stop-daemon --start --oknodo --chuid dhcp --group dhcp --umask 0007 --exec /opt/bin/dhcp-s -f /config/dhcp.cfg

# comment the above line, then run it from shell, run it in foreground!!!
$/opt/bin/dhcp-s -f /config/dhcp.cfg

write systemd service

/usr/lib/systemd/system is the path for service from rpm, pkg etc, so it’s common, if you want to add proxy due to your company, you should put specific conf for that service at /etc/systemd/system.

  • systemd service from pkg: /usr/lib/systemd/system
  • systemd service conf and local service not from pkg: /etc/systemd/system/

keywords

  • After=: only checks if the unit is activated already, and does not explicitly activate the specified units.
  • Requires=: The units listed in Requires are activated together with the unit. If any of the required units fail to start, the unit is not activated.
  • Wants=: This directive is similar to Requires= , but less strict. Systemd will attempt to start any units listed here when this unit is activated. If these units are not found or fail to start, the current unit will continue to function. This is the recommended way to configure most dependency relationships.

service daemon mode or not
As systemd must get the exit code to determine if the service starts or not, hence if service can NOT run in daemon mode, it must runs in background!!!, otherwise systemd can NOT know if it starts or not and always restart it again and again.

1
2
3
4
5
6
7
8
9
10
11
12
13
[Unit]
Description=Test
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
# runs in background
ExecStart=web.py &
Restart=on-failure

[Install]
WantedBy=default.target
1
2
3
4
5
6
7
8
9
10
11
12
13
[Unit]
Description=Test
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
# run in daemon mode
ExecStart=app.py -S
Restart=on-failure

[Install]
WantedBy=default.target

systemd parameters detail

simple systemd service named: onedrive.service

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
[Unit]
Description=OneDrive Free Client
Documentation=https://github.com/abraunegg/onedrive
# After multiple service
#
After=network-online.target abc.service
Requires=xyz.service
Wants=network-online.target

[Service]
Environment=BAR=default_bar_value
EnvironmentFile=/etc/conf.d/fooservice
Environment="HTTPS_PROXY=http://ip.address:port"
ExecStart=/usr/local/bin/onedrive --monitor
# restart on failure
Restart=on-failure
# sleep time before restart
# RestartSec=3

[Install]
WantedBy=default.target
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# show all active systemd service
$ systemctl --type=service

# show all active/inactive systemd service
$ systemctl --type=service --all

# Reload the service files to include the new service.
$ systemctl daemon-reload


# Start your service
$ systemctl start your-service.service

# To check the status of your service
$ systemctl status example.service

# To enable your service on every reboot
$ systemctl enable example.service

# To disable your service on every reboot
$ systemctl disable example.service

Set ENV for systemd service by two ways, inline or from file

1
2
3
4
5
[Service]
Environment=FOO=default_foo_value
Environment=BAR=default_bar_value
EnvironmentFile=/etc/conf.d/fooservice
ExecStart=/usr/bin/fooservice

later on to check the env of a given process by /proc/19571/environ

systemd restart
systemd services have start rate limiting enabled by default. If service is started more than StartLimitBurst times in StartLimitIntervalSec seconds is it not permitted to start any more. This parameters are inherited from DefaultStartLimitIntervalSec(default 10s) and DefaultStartLimitBurst(default 5) in /etc/systemd/system.conf, but you can disable start rate like this.

1
2
3
4
5
6
7
8
9
[Service]
Restart=always
# time to sleep before restarting a service
RestartSec=1

[Unit]
# StartLimitIntervalSec in recent systemd versions
StartLimitInterval=0
# StartLimitIntervalSec=0

systemd service parameter
In some case, service file can use variable that’s defined outside, like this
/usr/lib/systemd/system/crond.service

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[Unit]
Description=Command Scheduler
After=auditd.service systemd-user-sessions.service time-sync.target

[Service]
EnvironmentFile=/etc/sysconfig/crond
ExecStart=/usr/sbin/crond -n $CRONDARGS
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
RestartSec=30s

[Install]
WantedBy=multi-user.target

like $CRONDARGS and $MAINPID where are they defined, actually, they defined at
/etc/sysconfig/crond must has the same name(crond) without service as suffix, systemd daemon will read this file and pass variable to service.

1
2
3
# Settings for the CRON daemon.
# CRONDARGS= : any extra command-line startup arguments for crond
CRONDARGS=

debug systemd service

check stdout stderr log for systemd service

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# -b mean since recent boots
$ sudo journalctl --no-pager -b -u docker.service

# -p: Filter output by message priorities
# "emerg" (0), "alert" (1), "crit" (2),
# "err" (3), "warning" (4), "notice" (5),
# "info" (6), "debug" (7).
# If a single log level is specified, all messages with this log level or a lower (hence more important) log level are shown.
$ sudo journalctl --no-pager -b -u docker.service -p 4

# with time range(relative and absolute)
# last two hours ago
$ sudo journalctl --no-pager -u docker.service -p 4 -S -2h
# last 15 minutes ago
$ sudo journalctl --no-pager -u docker.service -p 4 -S -15m

$ TM=$(date "+%H:%M:%S") # wait a while
$ sudo journalctl -k -p err --no-pager --since=$TM

# since 9am
$ journalctl --since 09:00

# time range
$ journalctl --since "2015-01-10" --until "2015-01-11 03:00"

# show journal disk usage
$ sudo journalctl --disk-usage

change systemd log level to debug
/etc/systemd/system.conf

1
2
[Manager]
LogLevel=debug

check boot order of all systemd services

1
$ systemd-analyze plot > something.svg

auto mount

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# Centos7
$ sudo yum install -y autofs


# edit /etc/auto.master, make sure, create /nfs
/nfs /etc/auto.nfs

# create /etc/auto.nfs with below content for linux server
shared -fstype=nfs4,rw serverIP:/home/shared
#no password, default root user

# for windows server
shared -fstype=cifs,rw,uid=jason,gid=jason,username=xxx,password=xxx ://$server/shared

# mounted by jason:jason with user/password

# restart the service
$ sudo service autofs restart

# debug autofs
$ service autofs stop
$ automount -d -f -v

configure samba server

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
Linux export dir(run samba server), then Windows connects it with samba client.

Centos7
$ yum install samba samba-client
$ systemctl start smb.service
$ systemctl start nmb.service
$ systemctl enable smb.service
$ systemctl enable nmb.service

add samba user
$ sudo smbpasswd -a user1 (user1 must be a system user as well!!!)
edit /etc/samba/smb.conf with below content

# A publicly accessible directory, but read only, except for people in
# the "staff" group
[global]
log level = 5

[share]
comment = public share
path = /home/share
public = yes
writable = no
printable = no
valid users = user1 user2

sudo service smb restart

# check exported dir by samba server
smbclient -L 192.168.56.101

Enter SAMBA\root's password:

Sharename Type Comment
--------- ---- -------
onedrive Disk one drive
IPC$ IPC IPC Service (Samba 4.10.16)
Reconnecting with SMB1 for workgroup listing.

Server Comment
--------- -------

Workgroup Master
--------- -------
SAMBA DEV

# dump the samba config
testparm -v

# run in forground with level 3
smbd -i -d3

# check samba log: /var/log/samba
# check db cache at: /var/lib/samba/

share file between linux and linux by nfs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
through mount command,you can mount remote directory(linux) to the local machine over network. make sure the kernel supports nfs(server) before you use 'mount' command. by default Ubuntu disables nfs.

On server side

steps 1: install nfs if it is not installed
Ubuntu18
$sudo apt-get install nfs-kernel-server
Centos7
$yum install -y nfs-utils

steps 2: server exports a directory, edit /etc/exports file with something like this:
/home/share/ 192.168.1.20(rw,insecure,sync,all_squash)
/home/share/ 192.168.1.20(rw,insecure,sync,all_squash,anonuid=100,anongid=101)
/home/share/ 192.168.1.20(rw,insecure,sync,no_root_squash)
/home/share/ 192.168.1.20(rw,insecure,sync,no_root_squash,anonuid=100,anongid=101)
(override the attributes for clinet<-->192.168.1.20 )

[
nfsd bases its access control to files on the server machine on the uid and gid provided in each NFS RPC request. The normal behavior a user would expect is that she can access her files on the server just as she would on a
normal file system. This requires that the same uids and gids are used on the client and the server machine. This is not always true, nor is it always desirable.

Very often, it is not desirable that the root user on a client machine is also treated as root when accessing files on the NFS server. To this end, uid 0 is normally mapped to a different id: the so-called anonymous or
nobody uid. This mode of operation (called `root squashing') is the default, and can be turned off with no_root_squash.

By default, exportfs chooses a uid and gid of 65534 for squashed access. These values can also be overridden by the anonuid and anongid options. Finally, you can map all user requests to the anonymous uid by specifying the
all_squash option.

Here's the complete list of mapping options:

root_squash
Map requests from uid/gid 0 to the anonymous uid/gid. Note that this does not apply to any other uids or gids that might be equally sensitive, such as user bin or group staff.

no_root_squash
Turn off root squashing. This option is mainly useful for diskless clients.

all_squash
Map all uids and gids to the anonymous user. Useful for NFS-exported public FTP directories, news spool directories, etc. The opposite option is no_all_squash, which is the default setting.

anonuid and anongid
These options explicitly set the uid and gid of the anonymous account. This option is primarily useful for PC/NFS clients, where you might want all requests appear to be from one user. As an example, consider the
export entry for /home/joe in the example section below, which maps all requests to uid 150 (which is supposedly that of user joe).

steps 3: export the list
#sudo exportfs -a

steps 4: restart service
Ubuntu18
#sudo /etc/init.d/portmap restart
#sudo /etc/init.d/nfs-kernel-server restart

Centos7
$ systemctl start nfs-server
$ systemctl enable nfs-server

On client side
check the export list
#showmount -e $server_ip

steps 5: client mounts the dieretory
#sudo mount -t nfs serverip:/home/share /media/share

(don't support user and password, create a user belongs to other group,so the permission of this user is determined
by the configuration of /etc/exports )

首先mount后查看mount后的用户和组,然后登陆到export机器上查看该文件对该用户的权限,并作相应的更改
保证mount后的文件具有写权限

1.export中允许挂载后可以写【必须】
2.该文件对other 用户本身具有写权限【必须】
3.设置挂载点的权限,保证执行挂载的用户可以对该目录具有执行权限.
4.在mount 命令中加入 -o rw 参数【如果需要】

Permission denied when write on nfs dir, even export with RW
1. check the mount user at client, if it's root, make sure export with no_root_squash set.
2. check /etc/exports to see RW is set.

if you have anything wrong, please restart the service

B: show what nfs server exports to client!!!
#showmount -e remote_nfs_server
#showmount -e
show what my self exported by nfs

C: FAQ
"mount.nfs: access denied by server while mounting"
1 illegal port (client uses port larger than 1024)
cat /var/log/messages | grep mount
Jan 2 12:49:04 localhost mountd[1644]: refused mount request from 192.168.0.100 for /home/nfsshare/ (/home/nfsshare): illegal port 1689

FIX: add 'insecure' at server and restart nfs server

2 client and server use different nfs version
Try use other version to connect with server -o "vers=3"

mount -v -o "vers=3" -t nfs 10.117.7.201:/root/jason /media

3 client must have the right to local mount point like /media

run your task daily, weekly etc

use cron daemon to execute schedule job, there are two ways you can choose to run your task
one is user predefined period like daily, weakly, minutes etc, the other is defined own schedule whenever you want.

cron online tester

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
$ crontab filename [-u user]    用指定的文件替代(用户)目前的crontab。
$ crontab -1[-u user] 列出(用户)目前的crontab.
$ crontab -e[-u user] 编辑(用户)目前的crontab.
$ crontab -ri[-u user] 删除(用户)目前的crontab.


文件格式基本格式 :
*  *  *  *  * [username] command
分  时  日  月  周  命令

# ┌───────────── minute (0 - 59)
# │ ┌───────────── hour (0 - 23)
# │ │ ┌───────────── day of the month (1 - 31)
# │ │ │ ┌───────────── month (1 - 12)
# │ │ │ │ ┌───────────── day of the week (0 - 6) (Sunday to Saturday;
# │ │ │ │ │ 7 is also Sunday on some systems)
# │ │ │ │ │
# │ │ │ │ │
# * * * * *

* any value
, value list separator
- range of values
/ step values

第1列表示分钟1~59 每分钟用*或者 */1表示
第2列表示小时1~23(0表示0点)
第3列表示日期1~31
第4列表示月份1~12
第5列标识号星期0~6(0表示星期天)
第6列要运行的命令

crontab文件的一些例子:
/*脚本的地址必须是绝对地址*/
30 21 * * * /usr/local/etc/rc.d/lighttpd restart >> /var/log/root_crontab.log 2>&1
上面的例子表示每晚的21:30重启apache。

45 4 3,8,13,18,23,28 * * /usr/local/etc/rc.d/lighttpd restart
45 4 1,10,22 * * /usr/local/etc/rc.d/lighttpd restart
上面的例子表示每月1、10、22日的4 : 45重启apache。

10 1 * * 6,0 /usr/local/etc/rc.d/lighttpd restart
上面的例子表示每周六、周日的1 : 10重启apache。

0,30 18-23 * * * /usr/local/etc/rc.d/lighttpd restart
上面的例子表示在每天18 : 00至23 : 00之间每隔30分钟重启apache。

0 23 * * 6 /usr/local/etc/rc.d/lighttpd restart
上面的例子表示每星期六的11 : 00 pm重启apache。

* */1 * * * /usr/local/etc/rc.d/lighttpd restart
每一小时重启apache

* 23-7/1 * * * /usr/local/etc/rc.d/lighttpd restart
晚上11点到早上7点之间,每隔一小时重启apache

0 11 4 * mon-wed /usr/local/etc/rc.d/lighttpd restart
每月的4号与每周一到周三的11点重启apache

0 4 1 jan * /usr/local/etc/rc.d/lighttpd restart
一月一号的4点重启apache
Note:路径必须是绝对路径!!

Another way is use cron daemon cron is a daemon, which execute jobs under /etc hourly/weekly/monthly etc

$ ps -ef | grep cron (run as root)

$ ls /etc/cron*
cron.d/ cron.daily/ cron.hourly/ cron.monthly/ crontab cron.weekly/

$ service cron restart

write cron file under one of them, restart cron service to reload it

Note:

  1. file under cron.d/ and crontab must use the above format and [username] is a must for these two
  2. file under cron.xx just write with command, no time as xx means the time, no username is needed as it runs as root
  3. for daily/weekly/monthly, the exact time is determined by /etc/anacrontab refer to anacrontab format.

See anacron(8) and anacrontab(5) for details.

SHELL=/bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root

the maximal random delay added to the base delay of the jobs

RANDOM_DELAY=45

the jobs will be started during the following hours only

START_HOURS_RANGE=3-22

#period in days delay in minutes job-identifier command
1 5 cron.daily nice run-parts /etc/cron.daily
7 25 cron.weekly nice run-parts /etc/cron.weekly
@monthly 45 cron.monthly nice run-parts /etc/cron.monthly`


debug cron

  1. some checks

    • username is needed for jobs in cron.d and /etc/crontab are system jobs.
    • when username is used, should load user env from profile and set PATH for python, otherwise, cron has nothing with env(like $PATH set by profile not seen by cron)
    • 30 21 * * * user1 $HOME/.profile; /usr/local/etc/rc.d/lighttpd restart
  2. Redirect console log, it’s usually for error.
    30 21 * * * /usr/local/etc/rc.d/lighttpd restart >> /var/log/root_crontab.log 2>&1

  3. Check log $grep CRON /var/log/syslog OR $journalctl --no-pager -b -u crond.service

  4. Make sure cron is running $ps -ef | grep cron

  5. Check that the filename should NOT have an extension!!!

  6. Ensure the file has execute permissions

  7. Tell the system what to use when executing your script (eg. put #!/bin/sh at top)

  8. PATH is restricted to /bin:/usr/bin, if cmd not there, use absolute path

configure your own dns server by bind application

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
1 steps of configuring bind9
1.1 edit /etc/bind/name.conf.local with the content below
zone "example.com" {
type master;
file "/var/cache/bind/db.example.com";
allow-update {any;};
allow-transfer {any;};
allow-query {any;};

};
zone "0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.2.ip6.arpa" {
type master;
file "/var/cache/bind/db.rev.2000";
allow-update {any;};
allow-transfer {any;};
allow-query {any;};
};

1.2 #sudo mkdir /var/cache/bind
#sudo chown bind:bind /var/cache/bind
#edit /var/cache/bind/db.example.com with content below
$ORIGIN .
$TTL 604800 ; 1 week
example.com IN SOA ns1.example.com. root.example.com. (
2006020222 ; serial
604800 ; refresh (1 week)
86400 ; retry (1 day)
2419200 ; expire (4 weeks)
604800 ; minimum (1 week)
)
NS ns1.example.com.
$ORIGIN example.com.
ns1 AAAA 2000::1

#edit /var/cache/bind/db.rev.2000 with content below
$ORIGIN .
$TTL 10800 ; 3 hours
0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.2.ip6.arpa IN SOA ns1.example.com.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.2.ip6.arpa. root.example.com. (
2002111312 ; serial
28800 ; refresh (8 hours)
14400 ; retry (4 hours)
3600000 ; expire (5 weeks 6 days 16 hours)
86400 ; minimum (1 day)
)
NS ns1.example.com.
$ORIGIN 0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.2.ip6.arpa.

2 update AAAA using nsupdate
#nsupdate
>server 2000::1(specify the dns server)
>update add worf.example.com 7200 IN AAAA 2000::58(zone example.com must be configured at dns server)
>send (send the update)
3 query AAAA record
#dig @2000::1(dns server) worf.example.com AAAA

put file in memory

For faster run, you can put files in memory, create a mount point with tmpfs, then put files there, but files are lost when it’s umounted or system boots, actually, you do not need to create this ram disk by yourself, system already creates somes for you, it’s /run, /dev/shm

1
2
3
4
5
(base) [root@dev]# df -h
Filesystem Size Used Avail Use% Mounted on
devtmpfs 3.9G 0 3.9G 0% /dev
tmpfs 3.9G 0 3.9G 0% /dev/shm
tmpfs 3.9G 9.0M 3.9G 1% /run

run script at current shell not subshell

1
2
3
4
5
6
7
8
9
root@dev:/tmp# cat test.sh
#! /usr/bin/env bash
export http=1.0

root@dev:/tmp# source test.sh
root@dev:/tmp# echo $http
1.0

# likes you type export http=1.0 from the terminal!

dos and unix format

when you work both on windows and unix(linux), move files between them, be careful! as the file content may be changed due to os

linux和windows,Mac的行结束符是不同的,因此有些编辑器会无法正确的显示换行,这是编辑器 没有正确的处理行结束符导致的,但是有些强大的编辑器就能正确的显示不同文件类型, 无论是windows文件 还是unix,mac文件,当遇到编辑器无法正确显示的时候.

  • 首先确定文件的类型,在linux下运行file命令
  • 看编辑器是否支持该类型
  • 根据需要通过editplus–>document—>file format选项转化为能正确显示的文件类型。

• Window (CR/LF)
• Unix (LF)
• Mac (CR)

1
$ dos2unix dos_format_file

中文乱码的原因分析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
因此解决乱码的关键分三步
1.明确文件的编码格式
2.系统支持(安装)了这种编码格式
3.为应用程序设置此编码格式

乱码的原因就是编码格式的选择不对或者不兼容,使得解析错误!因此解决办法就是选择正确的编码格式,
任何应用程序都是调用系统默认或者本程序设定的编码格式,最终的都是调用系统安装的编码格式,去解析文件,

中文乱码的解决
1 显示系统支持的所有编码格式
$ locale -a
$ sudo apt-get install language-pack-zh-hant language-pack-zh-hans
(如果没有zh_CN 下载安装)
2 如果不支持中文编码格式,修改
sudo vi /var/lib/locales/supported.d/local
加入
zh_CN.GB18030 GB18030
zh_CN.GBK GBK
zh_CN.GB2312 GB2312
zh_HK.BIG5 BIG5
zh_TW.BIG5 BIG5
然后执行
#sudo locale-gen

check all encodings system support:
$ locale -a
zh_CN.gb18030
zh_CN.gb2312
zh_CN.gbk
zh_CN.utf8
zh_HK.big5
zh_HK.utf8
zh_SG.utf8
zh_TW.big5
zh_TW.utf8

3 为各种应用设置其编码格式gbk,或者gb2312
****step 1 and step 2 are a must for 中文乱码***

3.1 但是通过远程终端登录后,打开文件还是显示乱码
这是由于终端也有其编码格式,因此需要设置终端的编码格式为gbk或者gb2312,或者其他的编码格式,使其与文件内容的编码格式对应起来,具体设置方法参考终端的设置选项。
以上是常见的中文乱码的情况。

3.2 当远程登录后,英文乱码,出现??等情况,这是由于终端的编码格式和系统的编码格式不兼容导致的
因此通过locale查看系统的当前编码格式,然后设置终端的编码格式与其兼容就可以解决问题了。

3.3 mount(from windows)的中文文件名字显示 ?? 设置mount的iocharset 为utf-8
set iocharset to utf8 for mount option

-fstype=cifs,rw,iocharset=utf8,uid=ubuntu,gid=ubuntu,

vncserver

1
2
3
4
5
6
7
8
9
10
11
设置vncserver的分辨率,一种是修改配置文件,一种是启动vncserver的时候 通过参数传递,现在第二种方式更灵活,因此这里只介绍第二种方法:

#vncserver -geometry 1680x1050 -alwaysshared :1

这个命令包含了3个参数,第一个参数geometry表示分辨率,你可以指定适合自己桌面的分辨率;
第二个参数alwaysshared表示运行多个人同时连接到同一个桌面;
第三个参数:1表示开启一个1号远程桌面(如果该编号已经被占用,请选择其他的标号)
此时你可以使用ip:1来连接这个远程桌面。(注意:上面1280与800之间的连接符为英文字母x(xyz的x),而不是中英文的乘号!)

关闭一个远程桌面,可以使用如下命令:
$ vncserver -kill :1 其中,":1"表示的创建远程桌面时的桌面号

install sshd

1
2
3
4
5
6
7
8
9
10
11
12
13
Centos7
$ yum install -y openssh-server

# ssh client timeout after sometime
# edit sshd config and restart sshd service
# edit /etc/ssh/sshd_config
ClientAliveInterval 60

$ service sshd restart

# ssh terminal timeout due to “timed out waiting for input: auto-logout”
# edit ~/.bashrc
unset TMOUT

Reset by peer even iptable and firewall is disabled

1
2
3
4
5
6
7
8
$ grep sshd /var/log/syslog
Oct 16 08:59:45 openstack sshd[1214]: error: Could not load host key: /etc/ssh/ssh_host_rsa_key
Oct 16 08:59:45 openstack sshd[1214]: error: Could not load host key: /etc/ssh/ssh_host_dsa_key
Oct 16 08:59:45 openstack sshd[1214]: error: Could not load host key: /etc/ssh/ssh_host_ecdsa_key

# fix it(Ubuntu18)
$ sudo rm -r /etc/ssh/ssh*key
$ sudo dpkg-reconfigure openssh-server

only allow specific user to login

1
2
3
4
Edit /etc/ssh/sshd_config
add the statement

AllowUsers lzq

long delay when login with ssh

1
2
3
4
try:
ssh -o GSSAPIAuthentication=no user@yourserver
update /etc/ssh/sshd_config
UseDNS no

allow root user login with password by ssh

1
2
3
4
5
6
7
open /etc/ssh/ssd_config
Change
PermitRootLogin prohibit-password
PasswordAuthentication no
To
PermitRootLogin yes
PasswordAuthentication yes

specify user when connect with ssh server

1
2
3
$ ssh root@server
# OR
$ ssh server -l root

disable openssl popup window when use git

1
$ unset SSH_ASKPASS

ssh with password on command line

1
2
3
4
5
6
7
8
9
# Centos7
$ yum install -y sshpass

$ sshpass -p your_password ssh user@hostname

# change user password without prompt
$ echo -e -n "oldpasswd\nnewpasswd\nnewpasswd" | sudo passwd user
# OR
$ echo 'userid:newpasswd' | sudo chpasswd

launch GUI at ssh server by terminal

1
2
3
4
5
6
7
8
9
10
11
12
13
ssh server side
enable X11 on sshd by edit /etc/ssh/sshd_config

X11Forwarding yes

ssh client
While doing ssh use the option -X to enable X11 forwarding.
$ ssh username@hostname -X

OR

Enable trusted X11 forwarding, by using the -Y option,
$ ssh username@hostname -Y

run scp/ssh/sftp used in scripts without password input

key point is add the client public key to server's authorized_keys

use ssh-copy-id

1
2
3
4
5
6
7
8
9
10
# On client
$ ssh-keygen -t rsa (just enter is a must)
$ ssh-copy-id -f -i /home/lzq/.ssh/xx.pub root@serverip

# run command on remote server by ssh
$ ssh root@serverip "ls;pwd"

# enter particular dir after ssh login
$ ssh root@serverip "bash --login"
$ ssh root@serverip "cd xxx; bash --login"

OR

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# scp is used on client to copy data to server
# on client
$ mkdir -p /home/lzq/.ssh # create parent dir as well if not exist
# create private and public key pairs
$ ssh-keygen -t rsa (just enter, no other input)

# copy public key to ssh server
$ scp /home/lzq/.ssh/id_rsa.pub root@serverip:/root/.ssh/new.pub

# on server
$ cd /root/.ssh

if authorized_keys exists
$ cat new.pub >>authorized_keys
$ rm new.pub
else
$ mv new.pub authorized_keys

$ chmod 644 authorized_keys

# Client
$ ssh root@serverip

user management

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# show all processes of a given user
$ ps -u $user
$ pstree $user -ap
# show a process and its owner
$ ps u $pid

# show all processes of given group
$ ps -g $user
# show all groups from local and remote LDAP
$ getent group
# show all users from local and remote LDAP
$ getent passwd
# add a group with given id and name at local
$ groupadd [-g 6002] school
# create a system group
$ groupadd -r $group_name
# delete a group from local
$ groupdel $group_name


# show groups for current user
$ groups
# show groups for a given user
$ groups jason

# --- add a user to group does not effect for the given login
# --- you need to login again or use $ newgrp $group

# add/delete an existing user to a given group
$ gpasswd -a $user $group
$ gpasswd -d $user $group
$ gpasswd --members $user1, $user2 $group
# add user to given group
$ sudo usermod -a -G root jason # add jason to root group

# show id of current user
$ id -ru
# show current user
$ id -un
# show id of given user(local or remote)
$ id $user1

# add a new user or remove a user from local
# adduser [--home DIR] [--shell SHELL] [--no-create-home] [--uid ID] [--ingroup GROUP | --gid ID] [--disabled-password] [--disabled-login] user

# -r means deleting its home directory
$ userdel -r $user

# change passwd for current user
$ passwd
$ passwd $user

/etc/sudoers(Ubuntu18)

it’s a file used to control what commands a user can run

1
$ sudo visudo

/etc/sudoers

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# User privilege specification, root user can run all with any user on all hosts with any command!!!
root ALL = (ALL) ALL
[user] [host] = [runas user] commands

jorge ALL=(root) NOPASSWD: /usr/bin/find, /bin/rm
# user jorge can run as root user!!!
# the command must have absolute path!!!, user jorge can run /bin/rm as root without password required.

# Allow members of group sudo to execute any command after they have provided their password
%sudo ALL=(ALL) ALL

# Members of the admin group may gain root privileges
# allow members of group admin/users to execute any command with any user on all host without password.
%admin ALL= (ALL) NOPASSWD: ALL
%users ALL= (ALL) NOPASSWD: ALL
[group] [host] = (runas user) commands

/etc/sudoers example

1
2
3
4
5
lb 10.10.10.3 = (root) NOPASSWD: /usr/bin/find, /bin/rm
# OR
lb 10.10.10.1/24 = (root) NOPASSWD: /usr/bin/find, /bin/rm

# lb user can run /bin/rm as root without password on jason_dev host
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
lb@jason_dev$sudo rm xx
sudo unable to resolve host jason_dev(hostname of my machine)
# take long time to show such warning

# let's see how this happens and fix it

# step 1: check the user: lb, ok allowed to run /bin/rm
# step 2: check host(as lb is only allowed to run on 10.10.10.3
# we must know what's ip for current machine(jason_dev)
# check /etc/hosts, if not found
# DNSLookUp
# still not found, can't find get the above error)

# step 3: run rm with root and no password

# to avoid dnslook, add entry at /etc/hosts with

127.0.0.1 jason_dev

broadcast message to all users from terminal

1
2
3
4
5
6
7
$ wall 'hello everyone'

# send msg to one pts
$ who
root pts/8 2019-11-24 22:30 (10.20.6.117)
root pts/9 2019-11-25 23:59 (10.20.6.117)
$ write root pts/8

copy file from local to remote ssh server

1
2
3
# -r will follow symbol link
$ scp -r username@hostB:/home/lzq/vim .
$ scp -r vim username@hostB:/home/lzq/

backup file with progress bar locally

1
2
3
4
5
6
7
8
9
10
$ rsync -avP  /home/lzq/Document   /share/

# skip following symbol link
rsync -a --no-links vim root@hostB:/root/

# -a, --archive archive mode; equals -rlptgoD (no -H,-A,-X)
# -v, --verbose increase verbosity
# -P --progress

rsync -avP --no-links vim root@hostB:/root/
1
$ ln -s /home/lzq/* .

cfg file for shell

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
non-interactive terminal
bash/csh/sh /etc/bashrc and $HOME/.bashrc

interactive terminal
/etc/profile and $HOME/.profile


/etc/profile vs /etc/environment
System-wide environment variables
[
/etc/environment is not part of POSIX, it belongs to PAM (Pluggable Authentication Module), and only programs compiled with PAM support are able to use it (primarily login systems, which subsequently start the shell or user environment). This means it isn't even read by your shell.
--------------------------------------------------------------------------------------------------------
You can see the programs using /etc/environment with grep -l pam_env /etc/pam.d/*.
So /etc/environment is used for setting variables for programs which are usually not started from a shell
--------------------------------------------------------------------------------------------------------
]
A suitable file for environment variable settings that affect the system as a whole (rather than just a particular user) is /etc/environment. An alternative is to create a file for the purpose in the /etc/profile.d directory.

/etc/environment

This file is specifically meant for system-wide environment variable settings. It is not a script file, but rather consists of assignment expressions, one per line.

FOO=bar

Note: Variable expansion does not work in /etc/environment.



/etc/profile.d/*.sh

Files with the .sh extension in the /etc/profile.d directory get executed whenever a bash login shell is entered (e.g. when logging in from the console or over ssh), as well as by the DisplayManager when the desktop session loads.

You can for instance create the file /etc/profile.d/myenvvars.sh and set variables like this:

export JAVA_HOME=/usr/lib/jvm/jdk1.7.0
export PATH=$PATH:$JAVA_HOME/bin

Other files

While /etc/profile is often suggested for setting environment variables system-wide, it is a configuration file of the base-files package, so it's not appropriate to edit that file directly. Use a file in /etc/profile.d instead as shown above. (Files in /etc/profile.d are sourced by /etc/profile.)

/etc/default/locale is specifically meant for system-wide locale environment variable settings. It's written to by the installer and when you use Language Support to set the language or regional formats system-wide. On a desktop system there is normally no reason to edit this file manually.

The shell config file /etc/bash.bashrc is sometimes suggested for setting environment variables system-wide. While this may work on Bash shells for programs started from the shell, variables set in that file are not available by default to programs started from the graphical environment in a desktop session.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# Centos
$ /etc/centos-release
CentOS Linux release 7.9.2009 (Core)

# show cmdline of running kernel
$ cat /proc/cmdline

# change system time
$ date --set="2017-04-11 13:21:00"

# change timezone from command line
$ ln -s /usr/share/zoneinfo/US/Pacific /etc/localtime

# change hostname permanently
/etc/hostname (or /etc/HOSTNAME)

# show system reboot and shutodwn event
# NOTE: last read files from /var/log/wtmp or /var/log/btmp
$ last -xF reboot | head -3
reboot system boot 4.14.15-1.el7.el Fri May 17 04:45:16 2024 - Thu May 23 06:24:04 2024 (6+01:38)
reboot system boot 4.14.15-1.el7.el Fri May 10 06:37:05 2024 - Thu May 23 06:24:04 2024 (12+23:46)
reboot system boot 4.14.15-1.el7.el Fri May 10 06:29:01 2024 - Fri May 10 06:35:46 2024 (00:06)

$ last -xF shutdown

# show the latest reboot time
$ who -b
system boot 2024-05-17 04:45

$ uptime -s
2024-05-17 04:43:51

# show the lastest reboot
$ last -x reboot | head -1

# show how lang system boots
$ uptime

# disable selinux
$ setenforce 0 # temporary close selinux
OR
edit /etc/selinux/config

reset root password

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
In the event your Linux box experiences disk or file system issues you may receive a “Give root password for maintenance” prompt upon reboot. If you have your root password you can login but in the event your using ‘slide’ or ‘sudo’ for wheel access or you’ve just mis-placed your root password – you’ll need to reset it.

To reset your root password:
1. When the GRUB loader shows during boot press the spare bar to pause boot.

2. Select your boot kernel.

3. Type ‘e’ to edit the default kernel line.

4. Type ‘e’ again on the line that starts with ‘kernel’.

5. Add ‘init=/bin/bash’ to the end of the ‘kernel’ line then press enter.

6. Type ‘b’ to boot the modified kernel parameters.

7. Once you’re at the /bin/bash prompt you will need to remount the root file system as read/write in order to edit the passwd file:

# mount -o remount,rw /

8. Change your root password:

# passwd root

9. Remount the filesystem back to read only:

# mount -o remount,ro /

10. Reboot your server using CTR-ALT-DELETE.

11. You will now be able to login with your new root password and carry out the maintenance.

disable boot from save grub entry for grub2

1
2
3
4
5
6
7
8
9
10
11
12
13
Ubuntu18

GRUB_DEFAULT=saved
GRUB_SAVEDEFAULT=true

to

GRUB_DEFAULT=0
(always first entry)
GRUB_SAVEDEFAULT=false

then generate /boot/grub2/grub.cfg newly
#grub2-mkconfig -o /boot/grub2/grub.cfg

force enter command-line mode when boots

1
2
3
4
5
6
7
8
9
10
11
$sudo vi /etc/default/grub

Do below changes:
Comment the line GRUB_CMDLINE_LINUX_DEFAULT=”quiet splash”, by adding # at the beginning, which will disable the Ubuntu purple screen.
Change GRUB_CMDLINE_LINUX=”” to GRUB_CMDLINE_LINUX=”text”, this makes Ubuntu boot directly into Text Mode.
Uncomment this line #GRUB_TERMINAL=console, by removing the # at the beginning, this makes Grub Menu into real black & white Text Mode (without background image)

Ubuntu18
$ sudo update-grub
Centos7
$ grub2-mkconfig

enter single-user mode when boots

1
2
3
4
5
6
7
8
9
开机进入grub时,用上下键移到第二行的恢复模式,按e(注意不是回车)
把ro single 改成rw single init=/bin/bash , 然后按ctrl+x,就可以进入 单用户模式,完成后,按”ctrl+alt+delete“组合神键重启

passwd: Authentication token manipulation error
进入单用户模式后, filessystem may be mounted with readonly, so remount it again

mount -rw -o remount /
OR
mount -o remount, rw /

/etc/fstab file format

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
What is fstab file?

fstab is a configuration file that contains information of all the partitions and storage devices in your computer. The file is located under /etc, so the full path to this file is /etc/fstab.

/etc/fstab contains information of where your partitions and storage devices should be mounted and how. If you can't access your Windows partition from Linux, aren't able to mount your CD or write to your floppy as a normal user, or have problems with your CD-RW, you probably have a misconfigured /etc/fstab file. So, you can usually fix your mounting problems by editing your fstab file.

/etc/fstab is just a plain text file, so you can open and edit it with any text editor you're familiar with. However, note that you must have the root privileges before editing fstab. So, in order to edit the file, you must either log in as root or use the su command to become root.

Sample fstab file looks like this

#
# /etc/fstab
#
# <device> <mountpoint> <filesystemtype><options> <dump> <fsckorder>

/dev/hdb5 / ext2 defaults 1 1
/dev/hdb2 /home ext2 defaults 1 2
/dev/hdc /mnt/cdrom iso9660 noauto,ro,user 0 0
/dev/hda1 /mnt/dos/c msdos defaults 0 0
/dev/hdb1 /mnt/dos/d msdos defaults 0 0
/dev/fd0 /mnt/floppy ext2 noauto,user 0 0
/dev/hdb4 none ignore defaults 0 0

none /proc proc defaults
/dev/hdb3 none swap sw

Note that this system has two IDE partitions, one which is used as /, and the other used as /home. It also has two DOS partitions which are mounted under /mnt. Note the user option provided for the cdrom, and the floppy drive. This is one of the many default parameters you can specify. In this case it means that any user can mount a cdrom, or floppy disk. Other options will be dealt with later.

fstab file format explination

fstab consists of a number of lines (one for each filesystem) seperated into six fields. Each field is seperated from the next by whitespace (spaces/tabs).

So from the example given previously:

/dev/hdc /mnt/cdrom iso9660 noauto,ro,user 0 0

first field (/dev/hdc) is the physical device/remote filesystem which is to be described.

second field (/mnt/cdrom) specifies the mount point where the filesystem will be mounted.

third field (iso9660) is the type of filesystem on the device from the first field.

fourth field (noauto,ro,user) is a (default) list of options which mount should use when mounting the filesystem.

fifth field (0) is used by dump (a backup utility) to decide if a filesystem should be backed up. If zero then dump will ignore that filesystem. The sixth field (0) is used by fsck (the filesystem check utility) to determine the order in which filesystems should be checked.

If zero then fsck won't check the filesystem.

(as the example line above is a cdrom there is very little point in doing a fsck on it, so the value is zero).

File system mount options

As the filesystems in /etc/fstab will eventually be mounted using mount(8) it isn't surprising that the options field simply contains a comma-seperated list of options which will be passed directly to mount when it tries to mount the filesystem.

The options common to all filesystems are:

sync / async

All I/O to the file system should be done (a)synchronously.

auto

The filesystem can be mounted automatically (at bootup, or when mount is passed the -a option). This is really unnecessary as this is the default action of mount -a anyway.

noauto

The filesystem will NOT be automatically mounted at startup, or when mount passed -a. You must explicitly mount the filesystem.

dev / nodev

Permit any user to mount the filesyste. This automatically implies noexec,

exec / noexec

Permit/Prevent the execution of binaries from the filesystem.

suid / nosuid

Permit/Block the operation of suid, and sgid bits.

ro

Mount read-only.

rw

Mount read-write.

user

Permit any user to mount the filesystem. This automatically implies noexec, nosuid,nodev unless overridden.

nouser

Only permit root to mount the filesystem. This is also a default setting.

defaults

Use default settings. Equivalent to rw,suid,dev,exec,auto,nouser,async.

There are numerous options for the specific filesystes supported by mount.
However these are some of the more useful, for the full list check out the man page for `mount`.

ext2

check={none, normal, strict}
Sets the fsck checking level.

debug

print debugging info on each remount.

sb=n

n is the block which should be used as the superblock for the fs.

fat

check={r[elaxed], n[ormal], s[trict]}

Not the same as ext2. Rather deals with allowed filenames. See mount man page.

conv={b[inary], t[ext], a[uto]}

Performs DOS<->UNIX text file conversions automatically. See mount man page.

uid=n, gid=n

iso9660

norock

Disables Rock Ridge extensions.

fstab file Supported file systems list

affs - I have know idea what this is, if anyone else does please enlighten me.

coherent

ext - Don't use this. ext has been superseded by ext2.

ext2 - The standard Linux filesystem. (NB, this has nothing to do with extended partitions.)

fat - DOS.

hpfs - OS/2 High Performance File System.

iso9660 - CD-ROM's. Supports Rock Ridge extensions by default.

minix - can be useful for floppy disks.

msdos - Just fat with some addtional error checking.

nfs - Network FileSystem. Dealt with later.

proc - The process psudeo-filesystem now standard in Linux.

smb - Another network filesystem. Compatable with WFW, and NT. See Samba.

ufs - Unix FileSystem.

unsdos - Unix filesystem on a FAT partition.

vfat - MS's kludge of FAT to provide long filenames.

xenix

xiafs

deep in remove file

1
2
3
4
5
6
7
8
9
$ rm test.c
# actually, kernel takes two steps to delete the file
1. remove fentry(then you can NOT see test.c)
2. free inode of this file if its reference count is 0
Only these two steps executed, the disk space is freed

# show all deleted files(not see from disk), but still opened by process
$ lsof 2>/dev/null | grep deleted
ovsdb-ser 1089 openvswitch 7u REG 253,0 159 69471332 /tmp/tmpfVYsNnz (deleted)

what about app opens a large file, during it’s reading, someone rm that file?

Only fentry is deleted, inode is not freed, as when app opens that file,
it increments the reference of that inode
when app closes that file, at that time, it will be deleted from disk.

1
2
3
4
5
6
7
8
# check file inode
$ls -i a.c b.c
OR
$stat a.c b.c

$ mv a.c b.c
# actually, fentry(b.c) points to inode of (a.c)
# a.c(fentry is deleted), inode of (b.c) is freed if no use open it!!!

update file time

1
2
3
4
5
6
7
# Update the access and modification times of each FILE to the current time
$ touch test.doc
$ touch -d "2010-05-31 08:10:30" test.doc

# or change only one
$ touch -m -d "2010-05-31 08:10:30" test.doc
$ touch -a -d "2010-05-31 08:10:30" test.doc

cut command

1
2
3
# cut split string by tab by default, the first indiex if 1
$ echo "hello boy" | cut -d ' ' -f 1
hello

remove file named with special character

1
2
3
4
5
6
7
8
9
$ ls
#a.c -a.c

$ rm '#a.c'
$ rm \#a.c
$ rm ./-a.c

# use eval
$ eval "rm =1.3.0,"

display output to screen and also write it to file

1
$ echo "just a test" | tee log.txt

command xargs

1
2
3
4
5
6
7
# xargs will split parameters passed by tab or space, then call after command with splited parameter one by one
$ echo "hello boy" | xargs rm
rm: cannot remove 'hello': No such file or directory
rm: cannot remove 'boy': No such file or directory

# if you see xargs: argument line too long
$ xx | xargs -l1 rm # -l1 each time each parameter

find command(better use find file, not content of file)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# -name  exactly match!!!
# -iname case insensitive

# -type f | d | c | l(link) | b(block) | p(pipe)
# -size n[cwbkMG] # 1M, -1k
# -maxdepth 1 (max depth)
# -perm 755 (permission with 755)
# -user jason

$ find - type f -size +1k -name "/*test.c"

# when use | for find better to use -print0
$ find . -type f -print0 | xargs -0 rm -f

# more exec on some file
$ find . -type f -print0 -exec ls {} \; -exec rm -f {} \;

$ find . -type f -print0 -exec rm -f {} \;
# in some case it may meet error 'too long parameter/argument' something like use, use find | xargs to sovle it

print0: print the full file name on the standard output, followed by a null character (instead of the new-line character that ‘-print’ uses). This allows file names that contain newlines or other types of white space to be correctly interpreted by programs that process the find output. This option corresponds to the ‘-0’ option of xargs.

# find file with executable attribute
$ find . -executable

# negative
$ find . ! -name "*.txt"
# find with two or more conditions

$ find . -iname class.* -o -name basic*

rename a batch of files with pattern

1
2
3
$ rename 's/ //g' *.txt # remove space from filename
$ find . -type f -exec rename 's/ //g' {} \; # remove space from file name only
$ find . name "* *" -exec rename 's/ //g' {} \; # remove space from file name or dir name

show stats of a file

1
$ stat a.c

copy file

1
2
3
4
$ cp -r dir1 dir2 dir3/ # copy dir1, dir2(include hiden files) to dir3(under)

$ cp -r dir1/* dir2/
$ cp -r dir1/ dir2/ # copy all files(except hiden files) under dir1 to dir2

tar

1
2
3
4
5
6
7
8
9
10
# ERROR: Exiting with failure status due to previous errors
# 原来是待压缩的文件夹是root权限创建的,而执行tar的时候未加sudo

# create tar and exclude some dirs for files
$ tar czvf test.tar.gz test/ --exclude='test/exclude/'

# extract .xz with tar
$ tar -xJf xx.tar.xz
# extract .gz file
$ gunzip *.gz

sleep and usleep

1
2
3
4
5
sleep (sec);
usleep (microsec)

sec = 1000 milisecond 毫秒
milisecond = 1000 microsecond 微秒

history command

1
2
3
4
5
6
7
8
9
10
11
# show history command with time
$ export HISTTIMEFORMAT="`whoami` : | %F | %T: | "
# run history command
$ history
1 cd
2 ls

$ !2 # equal ls

# show latest N history commands
$ history 10

run command with a specific user or group

1
2
$ su -m jason -c 'ls' # jason is a user
$ sg - jason_group -c 'ls' # sg group

list all alias

1
$ alias -p

redirect shell output

1
2
3
# redirect stdout(1) to /dev/null
# and redirect stder(2) to stdout(1)
$ echo "hello" >/dev/null 2>&1

read one file at a time from a file

1
2
3
4
5
6
# read is a keyword
# line is var
where read -r line
do
echo $line
done < file

read input from standard input instead of a file

1
2
3
4
5
6
7
8
9
$ cat << END
hello boy
END

# read from std and write to a file
$ cat >new.txt << END
hello boy
END
# END is a marker can be any

git status can’t display chinese character

1
2
3
edit ~/.gitconfig
[core]
quotepath = false

check md5 value for a file

1
$ md5sum xx.iso

format man output and save it to a file

1
$ man strace | col -b > trace.txt

watch a command output by ‘n seconds’

1
2
# by default, free unix is KB -m means MB
$ watch -n 1 free -m

file encoding convertor iconv

1
2
3
4
5
$ iconv -l  # show supported encoding

$ file a.c # get file encoding

$ iconv -f one_encoding -t another_encoding a.c >b.c

error ‘sorry, you must have a tty to run sudo’

There must be Defaults requiretty in the file you try to edit.

generate uuid

1
$ uuidgen

formated json output from shell

1
$ echo '{"hostname":"test","domainname":"example.com"}' | python -m json.tool

Add an environment variable to a command

1
$ test=hello; echo $test

eval to run command from string

1
$ eval 'ls'

killall command not found

1
2
# Centos7
$ yum install -y psmisc

capture signal in shell

1
2
3
4
5
6
7
8
9
10
11
12
13
#!/bin/bash

# trap ctrl-c and call ctrl_c()
trap ctrl_c INT

function ctrl_c() {
echo "** Trapped CTRL-C"
}

for i in `seq 1 5`; do
sleep 1
echo -n "."
done

write message to /var/log/syslog by shell

1
2
3
4
5
#!/bin/bash
logger -t "title" "message" /* use tcp socket server port 601 */
logger -d "title" "message" /* use udp socket server port 514 */
logger -u /dev/log "title" "message"
# [looger is a command that can write syslog]

rsyslog conf

1
2
3
4
5
6
7
8
In /var/log/syslog you may see these kind of message
"Previous message repeated X times", where X is a number

it's useful for supressing message, but for debugging, you can't see it directly, turn it off by(ubuntu)

edit /etc/rsyslog.conf

$RepeatedMsgReduction off

wget

download particular files from particular website

1
2
3
4
5
$ wget -r -A .html http://cunit.sourceforge.net/doc/
$ wget -r --no-parent -A '*.deb' http://www.xyun.com/amd64/

# download all files except auto-generated index.html
$ wget -r -np -R "index.html*" http://example.com/configs/.vim/

wget breakpoint and retry

1
2
3
$ wget -c -t 10 $url
# -c breakpoin
# -t 0, number for retransmission, 0 always retry!

run a basic http server

1
$ python -m http.server 80 #python3

scan host on local network

1
2
3
4
5
6
7
8
9
# if you know the mac and you are on the local network
# you can easy to know the ip of that host(mac)

# will print IP, MAC
$ sudo arp-scan --interface=eth0 --localnet

# check if host(ip) opens a specific port
# check RDP port(windows remote desktop port)
$ sudo nmap -p 3389 $IP

resize disk(vm) after change its size

Afer you change vm disk by client, the free space of disk can be added to part of disk to expand its size

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
$ sudo fdisk -l
...
GPT PMBR size mismatch (20971519 != 209715199) will be corrected by w(rite).

-----new size 100G, old size 10G-----
Disk /dev/sda: 100 GiB, 107374182400 bytes, 209715200 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: 1C6DFAAE-5BA8-4141-A6CF-953F8D9E871F

----sda1 still use 10G-----
Device Start End Sectors Size Type
/dev/sda1 227328 20971486 20744159 9.9G Linux filesystem
/dev/sda14 2048 10239 8192 4M BIOS boot
/dev/sda15 10240 227327 217088 106M EFI System

$ sudo LANG=en_US.UTF-8 growpart /dev/sda 1
CHANGED: partition=1 start=227328 old: size=20744159 end=20971487 new: size=209487839,end=209715167

$ sudo fdisk -l
Disk /dev/sda: 100 GiB, 107374182400 bytes, 209715200 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: 1C6DFAAE-5BA8-4141-A6CF-953F8D9E871F

----sda1 has 100G, but the new add part should format with fs---
Device Start End Sectors Size Type
/dev/sda1 227328 209715166 209487839 99.9G Linux filesystem
/dev/sda14 2048 10239 8192 4M BIOS boot
/dev/sda15 10240 227327 217088 106M EFI System

$ sudo resize2fs /dev/sda1
resize2fs 1.44.1 (24-Mar-2018)
Filesystem at /dev/sda1 is mounted on /; on-line resizing required
old_desc_blocks = 2, new_desc_blocks = 13
The filesystem on /dev/sda1 is now 26185979 (4k) blocks long.

count line of code

There are lots of tools for counting code, two fast and popular ones, scc and tokei

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
$ go get -u github.com/boyter/scc/
$ scc [flags] [files or directories]
$ scc .
───────────────────────────────────────────────────────────────────────────────
Language Files Lines Blanks Comments Code Complexity
───────────────────────────────────────────────────────────────────────────────
Go 113 19031 2746 2181 14104 3360
Markdown 29 2701 655 0 2046 0
TOML 2 87 12 32 43 0
Makefile 1 41 6 17 18 0
Python 1 112 27 2 83 25
Shell 1 35 9 2 24 6
Smarty Template 1 25 3 0 22 5
Systemd 1 19 2 0 17 0
XML 1 1 0 0 1 0
gitignore 1 5 0 2 3 0
───────────────────────────────────────────────────────────────────────────────
Total 151 22057 3460 2236 16361 3396
───────────────────────────────────────────────────────────────────────────────

$ scc --by-file .
$ scc --exclude-dir vendor .

setup tcp/udp server with nc

nc is command to setup tcp(tls)/udp server or used as tcp/udp client

1
2
3
4
5
6
7
8
9
# start tcp server
$ nc -lv
nc -lv
Ncat: Version 7.50 ( https://nmap.org/ncat )
Ncat: Listening on :::31337
Ncat: Listening on 0.0.0.0:31337

# send tcp data with nc
$ echo "hello" | nc localhost 31337

check virtual disk real size

1
2
3
4
#  use -s option 
# disk size set 10G, but real size is 133M
$ ls -slh pod-23vmqfdjge-2021-09-08-21-00-07.raw
133M -rw-r--r-- 1 root root 10G Sep 8 20:51 pod-23vmqfdjge-2021-09-08-21-00-07.raw

timezone and ntpdate

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# show current timezone
$ ls -al /etc/localtime
lrwxrwxrwx. 1 root root 35 Sep 14 09:33 /etc/localtime -> ../usr/share/zoneinfo/Asia/Shanghai

# OR use command line
$ timedatectl status
Local time: Tue 2021-09-14 09:36:45 CST
Universal time: Tue 2021-09-14 01:36:45 UTC
RTC time: Tue 2021-09-14 01:36:51
Time zone: Asia/Shanghai (CST, +0800)
NTP enabled: yes
NTP synchronized: no
RTC in local TZ: no
DST active: n/a

# show all available zones
$ timedatectl list-timezones

# set correct zone
$ timedatectl set-timezone Asia/Shanghai

# ntpdate will update time with ntpserver to the zone you're using
# if you set zone incorrect, the time you get may be not expected.
$ ntpdate cn.pool.ntp.org
14 Sep 09:34:01 ntpdate[1524]: adjust time server 124.108.20.1 offset 0.028670 sec

# without ntp, set time by date directly, note for web GMT(UTC) is returned!!!
# so must with 'Z' suffix to convert to local time zone
$ date -s "$(curl -H'Cache-Control:no-cache' -sI baidu.com | grep '^Date:' | cut -d' ' -f3-6)Z"
# use proxychains for net proxy
$ date -s "$(proxychains -q curl -H'Cache-Control:no-cache' -sI baidu.com | grep '^Date:' | cut -d' ' -f3-6)Z"

# use proxychains for net proxy
$ date -s "$(proxychains -q curl -H'Cache-Control:no-cache' -sI google.com | grep '^Date:' | cut -d' ' -f3-6)Z"

ps aux

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
$ ps -aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.0 193888 7052 ? Ss 08:12 0:01 /usr/lib/systemd/systemd --switched-root --system --deserialize 22
root 2 0.0 0.0 0 0 ? S 08:12 0:00 [kthreadd]
root 4 0.0 0.0 0 0 ? S< 08:12 0:00 [kworker/0:0H]
root 6 0.0 0.0 0 0 ? S 08:12 0:00 [ksoftirqd/0]
root 7 0.0 0.0 0 0 ? S 08:12 0:00 [migration/0]
root 8 0.0 0.0 0 0 ? S 08:12 0:00 [rcu_bh]
root 9 0.0 0.0 0 0 ? S 08:12 0:00 [rcu_sched]

# state of process can be in below code
D Uninterruptible sleep (usually IO), in kerenl space, can not wake up by signal!!
R Running or runnable (on run queue)
S Interruptible sleep (waiting for an event to complete)
T Stopped, either by a job control signal(kill -STOP $pid) or because it is being traced.
Z Defunct ("zombie") process, terminated but not reaped by its parent. When a process finishes its task, it `releases the system resources it was using and cleans up its memory`. However,` its entry from the process table is not removed`, and its status is set as EXIT_ZOMBIE.

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), never swaped the memory out to disk!!!
s is a session leader
l is multi-threaded (using CLONE_THREAD, like NPTL pthreads do)
+ is in the foreground process group

# show more info(backtrace) about D process
$ echo w > /proc/sysrq-trigger
This command produces a report and a list of all processes in D state and a full kernel stack trace to /var/log/messages
$ grep 'state:D stack' /var/log/messages

# show all processes id in D state
$ ps axl | awk '$10 ~ /D/'

# show all processes in Zombine state
$ ps axl | awk '$10 ~ /Z/'

# show pstree of given process, show tree from 1 to its child with args

$ pstree -ansp 63044
systemd,1 --switched-root --system --deserialize 21
└─docker-containe,62978 c946e9c0e6845d4496d808c317d20a54086203932d940b103f9705322f4e9308 /var/run/docker/libcontainerd/c946e9c0e6845d4496d808c317d20a54086203932d940b103f9705322f4e9308 /usr/libexec/docker/docker-runc-current
└─(entry.sh,63044)



# pstree -ansp 115764, as you can seee under docker-containe,115764, there are many {docker-containe},$id which is thread of {docker.containe} process!!!
systemd,1 --switched-root --system --deserialize 21
└─docker-containe,115764 c946e9c0e6845d4496d808c317d20a54086203932d940b103f9705322f4e9308 /var/run/docker/libcontainerd/c946e9c0e6845d4496d808c317d20a54086203932d940b103f9705322f4e9308 /usr/libexec/docker/docker-runc-current
├─{docker-containe},115765
├─{docker-containe},115766
├─{docker-containe},115767
├─{docker-containe},115768
├─{docker-containe},115770
├─{docker-containe},115771
├─{docker-containe},115772
├─{docker-containe},115774
├─{docker-containe},115775
└─(tail,116336)

# clear process in D state
Reboot, Reboot!

# clear process in Z(zombine) state
We can’t really kill a zombie process since it’s already dead. However, there are a few workarounds we can use to clean up a zombie process
1. Manually send the SIGCHLD signal to the parent of a zombie process, it works only when parent process handles such signal!!! kill -s SIGCHLD $parent_pid
2. Kill parent process.

but if the parent process is init(pid 1), so that you can NOT kill init
This pretty much leaves you with two options.

- Manually modify the process table, eg. create a dummy process, link the [defunct process] as a child of the dummy, then kill them off. Quite dangerous, and you may have to manually clean up other process resources such as semaphores and file handles.

- Reboot the system

copy excludes some dir

1
2
3
4
# copy html dir to dev without sites/video
# The the --exclude path is relative to the source directly. Even if you put full absolute path, it will not work
# -v is for verbose, -a is for archive mode which means you want recursion and want to preserve almost everything
$ rsync -av --exclude 'sites/video' /var/www/html /var/www/dev

show start time of process

1
2
3
4
5
6
7
8
9
10
11
$ ps -eo pid,lstart,cmd
PID STARTED CMD
1 Mon Jan 24 11:21:04 2022 /usr/lib/systemd/systemd --system --deserialize 15
2 Mon Jan 24 11:21:04 2022 [kthreadd]
4 Mon Jan 24 11:21:04 2022 [kworker/0:0H]
6 Mon Jan 24 11:21:04 2022 [ksoftirqd/0]
7 Mon Jan 24 11:21:04 2022 [migration/0]
8 Mon Jan 24 11:21:04 2022 [rcu_bh]
9 Mon Jan 24 11:21:04 2022 [rcu_sched]
10 Mon Jan 24 11:21:04 2022 [lru-add-drain]
11 Mon Jan 24 11:21:04 2022 [watchdog/0]

ls output blinking ls /proc/pid/fd

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
$ ls -al /proc/9358/fd
total 0
dr-x------ 2 root root 0 Jan 28 14:11 .
dr-xr-xr-x 9 root root 0 Jan 28 14:11 ..
lrwx------ 1 root root 64 Jan 28 14:12 0 -> /dev/pts/4
lrwx------ 1 root root 64 Jan 28 14:12 1 -> /dev/pts/4
lrwx------ 1 root root 64 Jan 28 14:11 2 -> /dev/pts/4
lrwx------ 1 root root 64 Jan 28 14:12 3 -> socket:[985807] // inode number

# the last line is blinking as, it points to socket not a file on the disk

$ lsof -p 9358
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
s 9358 root cwd DIR 253,2 4096 2079103 /home/data/tmp
s 9358 root rtd DIR 253,0 4096 64 /
s 9358 root txt REG 253,2 17240 4216816 /home/data/tmp/s
s 9358 root mem REG 253,0 2156592 33841830 /usr/lib64/libc-2.17.so
s 9358 root mem REG 253,0 163312 33841791 /usr/lib64/ld-2.17.so
s 9358 root 0u CHR 136,4 0t0 7 /dev/pts/4
s 9358 root 1u CHR 136,4 0t0 7 /dev/pts/4
s 9358 root 2u CHR 136,4 0t0 7 /dev/pts/4
s 9358 root 3u unix 0xffff8fa41596b740 0t0 985807 /tmp/fd-pass.socket

top output

Top Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
$ top
top - 17:20:52 up 8:15, 6 users, load average: 0.02, 0.03, 0.05
Tasks: 216 total, 1 running, 215 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0.0 us, 0.7 sy, 0.0 ni, 99.3 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 8172968 total, 3056856 free, 1933172 used, 3182940 buff/cache
KiB Swap: 8257532 total, 8257532 free, 0 used. 5903604 avail Mem

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1 root 20 0 191832 4776 2620 S 0.0 0.1 0:07.57 systemd
2 root 20 0 0 0 0 S 0.0 0.0 0:00.02 kthreadd
4 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 kworker/0:0H
6 root 20 0 0 0 0 S 0.0 0.0 0:01.06 ksoftirqd/0



us - user cpu time (or) % CPU time spent in user space
sy - system cpu time (or) % CPU time spent in kernel space
ni - user nice cpu time (or) % CPU time spent on low priority processes
id - idle cpu time (or) % CPU time spent idle
wa - io wait cpu time (or) % CPU time spent in wait (on disk)
hi - hardware irq (or) % CPU time spent servicing/handling hardware interrupts
si - software irq (or) % CPU time spent servicing/handling software interrupts
st - steal time % CPU time in involuntary wait by virtual cpu while hypervisor is servicing another processor (or) % CPU time stolen from a virtual machine

NOTE: it is aggregate value, if you want to check usage for each CPU
press `top` then press 1.

top - 17:22:32 up 8:17, 6 users, load average: 0.00, 0.02, 0.05
Tasks: 216 total, 1 running, 215 sleeping, 0 stopped, 0 zombie
%Cpu0 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu1 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu2 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu3 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu4 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu5 : 0.3 us, 0.3 sy, 0.0 ni, 99.0 id, 0.0 wa, 0.0 hi, 0.3 si, 0.0 st
%Cpu6 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu7 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 8172968 total, 3056468 free, 1933540 used, 3182960 buff/cache
KiB Swap: 8257532 total, 8257532 free, 0 used. 5903236 avail Mem

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1856 mongod 20 0 1604016 116512 11132 S 0.3 1.4 2:23.77 mongod
2148 root 20 0 164024 6480 4952 S 0.3 0.1 0:15.29 sshd

NOTE: By default, the top will refresh the output every 3 seconds.


TIPS:
press `c` to show full path
press `o` to filter based on Field. example(support partial match): COMMAND=libvirt
press `=` to clear filter
press `e` to switch memory unit(kb, mb,gb,tb) for mem colums by default is kb

# sort by CPU or memory
$ top -o %CPU
$ top -o %MEM
# OR
$ top
then press
P
M (RES not VIRT)

# add more fields to see
TIP:
1 `press f` to show all fields
2 move cursor to the line
3 `press space` to define this line
4 `press right arrow` to select it then move the field to righ position

create iso file from command line

1
$ mkisofs -o test.iso $dir

setup proxy server

squid proxy

swap

change swap size by map it to a swap file setup swap file

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# check current swap size
$free -h
total used free shared buff/cache available
Mem: 31G 5.5G 25G 8.7M 870M 25G
Swap: 31G 0B 31G

$swapon -v
NAME TYPE SIZE USED PRIO
/dev/dm-1 partition 32G 0B -2

# check trend that swap is used from global, each cgroup can change it within that group
$cat /proc/sys/vm/swappiness

# temporary disable/enable swap
$swapon -a
# when swap is off, all data in swap(disk) will be swap in to memory!!! if not enough memory is avaiable, swapoff will fail with 'can
$swapoff -a

set process prority

Priority value(PRI) — The priority value is the process’s actual priority which is used by the Linux kernel to schedule a task.
In Linux system priorities are 0 to 139 in which 0 to 99 for real-time and 100 to 139 for users.

Nice value(NI) — Nice values are user-space values that we can use to control the priority of a process. The nice value range is -20 to +19 where -20 is highest, 0 default and +19 is lowest.

The relation between nice value and priority is as such
Priority_value = Nice_value + 20

1
2
3
4
5
6
7
8
9
# nice value(NI) can be range -20(highest) to 19(lowest)

# start process with nice value, threads will inherited parent's nice value
$ nice -5 ./app arg1

# change nice value after process starts(only change 1055, not it's children)
$ renice -n -10 -p 1055
# renice process which has multi-threads
$ renice -n -10 -p `ps --no-heading -Lo tid 1055`

split large file into smaller ones

Some website does not allow to upload larger file, split it into smaller ones.

1
2
3
4
5
6
7
8
9
10

# -d use digital sufffix
# -a one digital
# centos. as prefix
$ split -b 1G CentOS-7-x86_64-GenericCloud.qcow2 -d -a 1 centos.
centos.0 centos.1

# combine them to orignal one
# NOTE: not >>
$ cat centos.* > CentOS-7-x86_64-GenericCloud.qcow2

setup ftp server (centos)

The difference for modes is who is the initialator for data connection, for active mode, server always use 20 as the source port.

ftp active mode


In passive mode, the client uses the control connection to send a PASV command to the server and then receives a server IP address and server port number from the server, which the client then uses to open a data connection from an arbitrary client port to the server IP address and server port number received.

ftp passive mode

vsftpd

By default, vsftpd allows local users to login in and switch to its $HOME

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$ yum install vsftpd
$ service vsftpd start

# edit /etc/vsftpd/vsftpd.conf

# Use virtual HOME for local user not $HOME/$USER
# https://www.ryadel.com/en/vsftpd-configure-different-home-folder-each-user-specific-directory/


# test it

$ yum install -y ftp
# standard port 21 for ftp
$ ftp localhost

# open on different port
$ ftp
ftp>open localhost 6621

ps command advanced

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# fields of aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND

# show top 5 cpu usage processes
$ ps aux --sort -%cpu| head -n 6
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
openvsw+ 1353 0.6 0.1 1220748 51412 ? S<Lsl 17:44 0:28 ovs-vswitchd unix:/var/run/openvswitch/db.sock -vconsole:emer -vsyslog:err -vfile:info --mlockall --user openvswitch:openvswitch --no-chdir --log-file=/var/log/openvswitch/ovs-vswitchd.log --pidfile=/var/run/openvswitch/ovs-vswitchd.pid --detach
mysql 2086 0.2 1.1 1980300 389644 ? Ssl 17:44 0:11 /usr/sbin/mysqld
root 1 0.0 0.0 191528 4520 ? Ss 17:44 0:01 /usr/lib/systemd/systemd --switched-root --system --deserialize 22
root 2 0.0 0.0 0 0 ? S 17:44 0:00 [kthreadd]
root 4 0.0 0.0 0 0 ? S< 17:44 0:00 [kworker/0:0H]

# show the first 5 memory usage processes, by default memory unit is KB!!!
$ ps aux --sort -%mem | head -n 6
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
mysql 2086 0.2 1.1 1980300 389644 ? Ssl 17:44 0:11 /usr/sbin/mysqld
root 1796 0.0 0.2 274540 76708 ? S 17:44 0:02 /home/data/Anaconda3/envs/py3.9/bin/python3.9 /home/data/Anaconda3/envs/py3.9/bin/jupyter-notebook -y --no-browser --allow-root --ip=172.17.0.2 --port=8080 --notebook-dir=/home/data/jupyter
openvsw+ 1353 0.6 0.1 1220748 51412 ? S<Lsl 17:44 0:28 ovs-vswitchd unix:/var/run/openvswitch/db.sock -vconsole:emer -vsyslog:err -vfile:info --mlockall --user openvswitch:openvswitch --no-chdir --log-file=/var/log/openvswitch/ovs-vswitchd.log --pidfile=/var/run/openvswitch/ovs-vswitchd.pid --detach
root 1794 0.0 0.0 574288 17504 ? Ssl 17:44 0:00 /usr/bin/python2 -Es /usr/sbin/tuned -l -P
polkitd 1060 0.0 0.0 614316 11136 ? Ssl 17:44 0:00 /usr/lib/polkit-1/polkitd --no-debug

# show thread info of given process
# -L Show threads, possibly with LWP and NLWP columns.
$ ps -Lf 13430
UID PID PPID LWP C NLWP STIME TTY STAT TIME CMD
root 13430 13429 13430 0 11 Jun20 ? Ssl 0:32 node --no-warnings /root/.vim/bundle/coc.nvim/build/index.js
root 13430 13429 13431 0 11 Jun20 ? Ssl 0:00 node --no-warnings /root/.vim/bundle/coc.nvim/build/index.js
root 13430 13429 13432 0 11 Jun20 ? Ssl 0:00 node --no-warnings /root/.vim/bundle/coc.nvim/build/index.js
root 13430 13429 13433 0 11 Jun20 ? Ssl 0:00 node --no-warnings /root/.vim/bundle/coc.nvim/build/index.js
root 13430 13429 13434 0 11 Jun20 ? Ssl 0:00 node --no-warnings /root/.vim/bundle/coc.nvim/build/index.js
root 13430 13429 13435 0 11 Jun20 ? Ssl 0:00 node --no-warnings /root/.vim/bundle/coc.nvim/build/index.js
root 13430 13429 13436 0 11 Jun20 ? Ssl 0:00 node --no-warnings /root/.vim/bundle/coc.nvim/build/index.js
root 13430 13429 13479 0 11 Jun20 ? Ssl 0:00 node --no-warnings /root/.vim/bundle/coc.nvim/build/index.js
root 13430 13429 13480 0 11 Jun20 ? Ssl 0:00 node --no-warnings /root/.vim/bundle/coc.nvim/build/index.js
root 13430 13429 13481 0 11 Jun20 ? Ssl 0:00 node --no-warnings /root/.vim/bundle/coc.nvim/build/index.js
root 13430 13429 13482 0 11 Jun20 ? Ssl 0:00 node --no-warnings /root/.vim/bundle/coc.nvim/build/index.js

# show thread name of a process
$ ps -L -o tid,pid,comm 19562
PID TID COMMAND
19562 19562 qemu-kvm
19562 19565 qemu-kvm
19562 19566 qemu-kvm
19562 19567 IO iothread1
19562 19571 CPU 0/KVM
19562 19572 CPU 1/KVM
19562 19574 vnc_worker

# show custom output for given process
$ ps -eo user,pid,ppid,%cpu,%mem,vsz,rss,pri,ni,start,time,cmd -fp $pid

# show custom output and more
$ ps -eo user,pid,ppid,%cpu,%mem,vsz,rss,pri,ni,start,time,cmd
USER PID PPID %CPU %MEM VSZ RSS PRI NI STARTED TIME CMD
root 1 0 0.0 0.0 191528 3216 19 0 Jan 11 00:00:09 /usr/lib/systemd/systemd --switched-root --system --deserialize 22
root 2 0 0.0 0.0 0 0 19 0 Jan 11 00:00:00 [kthreadd]
root 4 2 0.0 0.0 0 0 39 -20 Jan 11 00:00:00 [kworker/0:0H]
root 6 2 0.0 0.0 0 0 19 0 Jan 11 00:00:03 [ksoftirqd/0]
root 7 2 0.0 0.0 0 0 139 - Jan 11 00:00:00 [migration/0]
root 8 2 0.0 0.0 0 0 19 0 Jan 11 00:00:00 [rcu_bh]

# custom fields with sorting
$ ps -eo user,pid,ppid,%cpu,%mem,vsz,rss,pri,ni,start,time,cmd --sort=%cpu
$ ps -eo user,pid,ppid,%cpu,%mem,vsz,rss,pri,ni,start,time,cmd --sort=%mem

# The "+" is optional since default direction is increasing numerical or lexicographic order
$ ps -eo user,pid,ppid,%cpu,%mem,vsz,rss,pri,ni,start,time,cmd --sort=+rss
$ ps -eo user,pid,ppid,%cpu,%mem,vsz,rss,pri,ni,start,time,cmd --sort=rss

# top five memory usage process
$ ps -eo user,pid,ppid,%cpu,%mem,vsz,rss,pri,ni,start,time,cmd --sort=-rss | head -6

# show memory in MB unit(format field 7) only support format one field by numfmt!!
$ ps -eo user,pid,ppid,%cpu,%mem,vsz,rss,pri,ni,start,time,cmd --sort=-rss | numfmt --header --field 7 --to=iec --from-unit=1024

# show rss field value(default unit KB) only
$ps -q 1354 -o rss=
51464
# show given process only
$ ps -fp $pid

# there are two process PID 1 and PID 2 which have no parent!
# all user processes are child of PID 1
# all kernel processes are child of PID 2
# UID PID PPID C STIME TTY TIME CMD
# root 1 0 0 Mar08 ? 00:00:59 /usr/lib/systemd/systemd --switched-root --system --deserialize 21
# root 2 0 0 Mar08 ? 00:00:02 [kthreadd]

# only show user application process not kernel thread
$ ps -ef | awk '$3!="2" {print $0}'
# only show kernel thread
$ ps -ef | awk '$3=="2" {print $0}'

sort command advaned

refer to sort example

run python service from virtual env

Edit your serivce file like this

1
2
3
4
5
6
7
8
9
# /root/py3.8 is virtual env
$ cat /etc/systemd/system/test.service
...
ExecStart=/root/py3.8/bin/python /root/me/auto-tools/tool/web.py &
...

# reload service file
$ systemctl daemon-reload
$ service test restart

encrypt a file

1
2
3
4
5
6
7
8
$ yum install -y gnupg
# prompt to input password for encryption
$ gpg --cipher-algo AES256 -c file
$ gpg -d file.gpg

# with output file
$ gpg -o encrypt --cipher-algo AES256 -c file
$ gpg -o file -d encrypt

disable cpu without reboot system

1
2
3
4
5
6
7
8
9
10
11
###########One way############################
$ chcpu -d 1-10
$ chcpu -d 1
$ chcpu -e 1

###########One way############################
$ echo 0 > /sys/devices/system/cpu/cpu1/online
$ echo 1 > /sys/devices/system/cpu/cpu1/online

# show online processor
$ grep processor /proc/cpuinfo

show hardware meta

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
$ lshw
description: Rack Mount Chassis
product: PowerEdge R630 (SKU=NotProvided;ModelName=PowerEdge R630)
vendor: Dell
serial: 91TYB72
width: 64 bits
capabilities: smbios-2.8 dmi-2.8 vsyscall32
configuration: boot=normal chassis=rackmount sku=SKU=NotProvided;ModelName=PowerEdge R630 uuid=44454C4C-3100-1054-8059-B9C04F423732
*-core
description: Motherboard
product: 0CNCJW
vendor: Dell
physical id: 0
version: A08
serial: .91TYB72.CN747515840576.
*-firmware
description: BIOS
vendor: Dell
physical id: 0
version: 1.3.6
date: 06/03/2015
size: 64KiB
capacity: 15MiB
capabilities: isa pci pnp upgrade shadowing cdboot bootselect edd int13floppytoshiba int13floppy360 int13floppy1200 int13floppy720 int9keyboard int14serial int10video acpi usb biosbootspecification netboot uefi
*-cpu:0
description: CPU
product: Xeon
vendor: Intel Corp.
physical id: 400
bus info: cpu@0
version: Intel(R) Xeon(R) CPU E5-2640 v3 @ 2.60GHz
slot: CPU1
size: 2600MHz
capacity: 4GHz
width: 64 bits
clock: 3705MHz
... more

$ lshw -class disk
*-disk:0
description: SCSI Disk
product: PERC H730 Mini
vendor: DELL
physical id: 2.0.0
bus info: scsi@0:2.0.0
logical name: /dev/sda
version: 4.25
serial: 009bf0a4080e81572100a1d44820844a
size: 558GiB (599GB)
capabilities: partitioned partitioned:dos
configuration: ansiversion=5 logicalsectorsize=512 sectorsize=512 signature=000ddb8f

use /dev/urandom

It’s a file like device, so you can cat it or copy from it

1
2
3
4
5
6
7
8
9
10
11
# 4K of random bytes
$ dd if=/dev/urandom of=~/urandom_test count=4 bs=1024

# quit until ctrl + c
$ cat /dev/urandom > ~/urandom_test2

# 30 lines of random
$ head -30 /dev/urandom > ~/urandom_test3

# 30 bytes of random
head -c 30 /dev/urandom > random.bytes

no space left on system

There are two possible reasons that may cause this.

  • no enough space
  • no enough inode
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# disk which disk is full
$ df -h
Filesystem Size Used Avail Use% Mounted on
devtmpfs 440M 0 440M 0% /dev
tmpfs 464M 0 464M 0% /dev/shm
tmpfs 464M 13M 451M 3% /run
tmpfs 464M 0 464M 0% /sys/fs/cgroup
/dev/vda1 8.0G 1.1G 7.0G 14% /
tmpfs 119M 0 119M 0% /run/user/0
# inside that disk, check whih dir uses the much space
$ cd /home/data
$ du -h -d 1
7.0G ./Anaconda3
0 ./jupyter
23G ./github
3.3G ./tmp
1.6G ./onedrive
34G .

# inode
$ df -i
Filesystem Inodes IUsed IFree IUse% Mounted on
devtmpfs 2.0M 451 2.0M 1% /dev
tmpfs 2.0M 2 2.0M 1% /dev/shm
tmpfs 2.0M 721 2.0M 1% /run
tmpfs 2.0M 16 2.0M 1% /sys/fs/cgroup
/dev/mapper/centos_dev-root 50M 363K 50M 1% /
/dev/mapper/centos_dev-home 150M 580K 150M 1% /home
/dev/mapper/centos_dev-var 25M 90K 25M 1% /var
/dev/sda1 150K 370 150K 1% /boot
tmpfs 2.0M 366 2.0M 1% /run/user/0
overlay 25M 90K 25M 1% /var/lib/docker/overlay2/bec9168000402c04316e112d231a51fa1ba120b7e09c5ab65014b80f3161b6b6/merged

# to see inodes used for each subdir
$ find . -xdev | cut -d "/" -f 2 | sort | uniq -c | sort -n -r | head -10
285913 Anaconda3
226484 github
760 onedrive
11 tmp
11 jupyter

systemd socket activation

how socket activation works and systemd for developer

lsmem and free show different total memory

lsmem lists memory blocks and their state; these reflect physical memory and are counted in units of memory blocks, i.e. 128MiB on your system. To do this, lsmem reads information made available by the kernel in /sys/devices/system/memory. On your system, the kernel tracks 64 memory blocks for a total of 8GiB.

free lists memory that’s usable by the system; “total” is the amount of physical memory, minus memory reserved by the system (for the firmware’s purposes mostly) and the kernel’s executable code. free reads this information from /proc/meminfo.

change PS1 env

1
2
3
4
5
6
7
# \u    --->user
# \h --->hostanme
[root@A04-R08-I138-44-3G1ZBS2 ~] $ echo $PS1
[\u@\h \W]\$

[root@A04-R08-I138-44-3G1ZBS2 ~] $ export PS1="[\u@node-debug \W]$ "
[root@node-debug ~]$

proxy setting

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# global setting, this works only when application use such environment variable
$ cat ~/.bashrc
export http_proxy='http://10.226.198.162:3128'
export https_proxy='http://10.226.198.162:3128'

# application provides its own way for proxy
# git proxy
$ git config --global https.proxy http://127.0.0.1:1080
$ git config --global https.proxy https://127.0.0.1:1080
$ git config --global http.proxy 'socks5://127.0.0.1:1080'
$ git config --global https.proxy 'socks5://127.0.0.1:1080'
$ git config --global --unset http.proxy/su
$ git config --global --unset https.proxy

# npm proxy
$ npm config set proxy http://127.0.0.1:1080

# docker proxy
$ mkdir -p /etc/systemd/system/docker.service.d

$ touch /etc/systemd/system/docker.service.d/http-proxy.conf
[Service]
Environment="HTTP_PROXY=http://user01:password@10.10.10.10:8080/"
Environment="HTTPS_PROXY=https://user01:password@10.10.10.10:8080/"
Environment="NO_PROXY= hostname.example.com,172.10.10.10"

$ systemctl show docker --property Environment

# go proxy
$ go env
GOPROXY="https://goproxy.io,direct"

# yum proxy
$ cat /etc/yum.conf
[main]
proxy=http://192.226.198.162:3128

# pip proxy or set global HTTP_PROXY
$ pip install --proxy http://user:password@proxyserver:port TwitterApi

# proxychains to force any application to use proxy
# NOTE: it supports TCP only (no UDP/ICMP etc).
$ yum install proxychains-ng
$ cat /etc/proxychains.conf
strict_chain
proxy_dns
remote_dns_subnet 224
tcp_read_time_out 15000
tcp_connect_time_out 8000
[ProxyList]
http 192.226.136.231 3128
# then run app this way
$ proxychains pip install ipvsd

process limits

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# global setting(default for process, but can be reset by process)
$ ulimit -a
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 1030598
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
open files (-n) 102400
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 10240
cpu time (seconds, -t) unlimited
max user processes (-u) 307200
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited

# real limits of each process

$ cat /proc/116446/limits
Limit Soft Limit Hard Limit Units
Max cpu time unlimited unlimited seconds
Max file size unlimited unlimited bytes
Max data size unlimited unlimited bytes
Max stack size 10485760 20971520 bytes
Max core file size 0 unlimited bytes
Max resident set unlimited unlimited bytes
Max processes 307200 307200 processes
Max open files 204800 204800 files
Max locked memory 65536 65536 bytes
Max address space unlimited unlimited bytes
Max file locks unlimited unlimited locks
Max pending signals 1030598 1030598 signals
Max msgqueue size 819200 819200 bytes
Max nice priority 0 0
Max realtime priority 0 0
Max realtime timeout unlimited unlimited us

random lines

use shuf to write a random permutation of the input lines to standard output.

1
2
3
4
5
# standoutput
$ shuf new.txt

# file as output
$ shuf new.txt -o random.txt

pgrep vs pidof

The programs pgrep and pidof are not quite the same thing, but they are very similar. For example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$ pidof 'firefox'
5696
$ pgrep '[i]ref'
5696
$ pidof '[i]ref'
$ printf '%s\n' "$?"
1

# get children process(not thread) of given pid
$ pgrep -P 1824
1825


# it shows process and threads as well
# 1694, 1695 are threads not process
$ pstree -p 1824
dnsmasq(1824)───dnsmasq(1825)

As you can see, pidof failed to find a match for [i]ref. This is because pidof program returns a list of all process IDs associated with a program called program. On the other hand, pgrep re returns a list of all process IDs associated with a program whose name matches the regular expression re.

In their most basic forms, the equivalence is actually: $ pidof 'program' == $ pgrep '^program$'

remove cgroup from /sys/fs

First you have to move all processes from this cgroup, then delete it, otherwise it, error shows cgroups can't be cleaned up: Device or resource busy

1
2
3
4
5
6
7
8
# use cpu cgroup as an example
$ cat /sys/fs/cgroup/cpu/test/cgroup.procs
8666
# move 8666 to root group, also moved it from test group
$ echo 8666 >/sys/fs/cgroup/cpu/cgroup.procs

$ cat /sys/fs/cgroup/cpu/test/cgroup.procs
$ rmdir /sys/fs/cgroup/cpu/test

find all shell scripts

1
2
3
4
5
6
7
$ find /xyz | xargs file | grep shell
./david/query-docker.sh: Bourne-Again shell script, ASCII text executable
./david/db/import-db.sh: POSIX shell script, ASCII text executable, with very long lines

$ find /xyz | xargs file | grep shell | cut -d ":" -f1
./david/query-docker.sh
./david/db/import-db.sh

add time out for any shell command

1
2
3
4
5
6
7
8
9
$ timeout 5s ping www.sd

# capture output of command
$ RET=$(timeout 5s ls asd 2>&1)
$ echo $RET

# sometimes it will hang when capture command output, to solve this add '--foreground' option
$ RET=$(timeout --foreground 5s $CMD 2>&1)
$ echo $RET

which numa memory by a process

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# list all memory used by a process
# numa bind policy for huage page, default policy for others
$ cat /proc/82389/numa_maps
7f069ab9a000 default file=/usr/lib64/ld-2.17.so anon=1 dirty=1 N0=1 kernelpagesize_kB=4
7f0588000000 bind:0-1 file=/mnt/huge_2MB/libvirt/qemu/141-i-f2w3m8owht/qemu_back_mem._objects_ram-node0.2IyOfZ\040(deleted) huge dirty=2048 mapmax=4 N0=2048 kernelpagesize_kB=2048
# the first column is memory address
# the second column is numa node used by this memory
# default means all numa nodes
# bind:0-1 means only numa node 0 and node 1 are allowed for this memory, but we may only used one node.
# the third column is file related
# the last column is kernel page for this memory
# the one before last colum is the page count of this memory on each node
# N0=2048 means allocate 2048*kernelpagesize_kB on node 0

$ numastat -p 82389
Per-node process memory usage (in MBs) for PID 82389 (qemu-kvm)
Node 0 Node 1 Total
--------------- --------------- ---------------
Huge 4096.00 0.00 4096.00
Heap 65.16 0.00 65.16
Stack 0.03 0.00 0.04
Private 32.34 1.21 33.55
---------------- --------------- --------------- ---------------
Total 4193.53 1.21 4194.74

# total numa stat
$ numastat
node0 node1
numa_hit 271446988685 306962573062
numa_miss 144931 15014353674
numa_foreign 15014353674 144931
interleave_hit 35352 35604
local_node 271445218315 306961782987
other_node 1915301 15015143749


# huage page on two numa nodes
$numastat -p 1144
Per-node process memory usage (in MBs) for PID 1144 (qemu-kvm)
Node 0 Node 1 Total
--------------- --------------- ---------------
Huge 1752.00 6440.00 8192.00
Heap 1.04 44.79 45.82
Stack 0.00 0.04 0.04
Private 16.66 11.42 28.08
---------------- --------------- --------------- ---------------
Total 1769.70 6496.25 8265.95

# as you can see N0(node 0) 876*2M and N1(node 1) 3220*2M
# numa bind policy
$ cat /proc/1144/numa_maps | grep 2048
7fbd58000000 bind:0-1 file=/mnt/huge_2MB/libvirt/qemu/38-i-y4s8f9zg2o/qemu_back_mem._objects_ram-node0.dlp9WP\040(deleted) huge dirty=4096 mapmax=4 N0=876 N1=3220 kernelpagesize_kB=2048

# numa prefer policy for huge page

# prefre node 1 but huage page is allocated at node0(N0) 12G and node1(N1) 20G
$ cat /proc/140662/numa_maps | grep 1G
7f5480000000 prefer:1 file=/mnt/huge_1GB/qemu_back_mem._objects_ram-node0.8Jxnog\040(deleted) huge anon=32 dirty=32 N0=12 N1=20 kernelpagesize_kB=1048576

check initrd.img

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# list content of initrd
$ lsinitrd build/initrd.img
mage: build/nc-initrd.img: 31M
========================================================================
Version:

Arguments:
dracut modules:
========================================================================
drwxr-xr-x 11 root root 0 Mar 8 11:30 .
drwxr-xr-x 2 root root 0 Mar 8 11:30 bin
lrwxrwxrwx 1 root root 13 Mar 8 11:30 bin/hwclock -> /sbin/busybox
lrwxrwxrwx 1 root root 13 Mar 8 11:30 bin/sh -> /sbin/busybox
lrwxrwxrwx 1 root root 13 Mar 8 11:30 bin/tar -> /sbin/busybox
drwxr-xr-x 2 root root 0 Mar 8 11:30 dev
-rwxr-xr-x 1 root root 568240 Mar 8 11:30 init
drwxr-xr-x 2 root root 0 Mar 8 11:30 kdump_tools
-rw-r--r-- 1 root root 10162077 Mar 8 11:30 kdump_tools/initramfs-4.14.121-jdcloudkdump.img
-rw-r--r-- 1 root root 4964304 Mar 8 11:30 kdump_tools/vmlinuz-4.14.121-jdcloud
drwxr-xr-x 3 root root 0 Mar 8 11:30 lib
drwxr-xr-x 2 root root 0 Mar 8 11:30 lib64
-rwxr-xr-x 1 root root 163312 Mar 8 11:30 lib64/ld-linux-x86-64.so.2
-rwxr-xr-x 1 root root 13536 Mar 8 11:30 lib64/libfreebl3.so
-rwxr-xr-x 1 root root 553072 Mar 8 11:30 lib64/libfreeblpriv3.so
-rwxr-xr-x 1 root root 287312 Mar 8 11:30 lib64/libnspr4.so
-rwxr-xr-x 1 root root 737664 Mar 8 11:30 lib64/libnss3.so
-rwxr-xr-x 1 root root 585848 Mar 8 11:30 lib64/libnssckbi.so
-rwxr-xr-x 1 root root 152576 Mar 8 11:30 lib64/libnssdbm3.so
-rwxr-xr-x 1 root root 175464 Mar 8 11:30 lib64/libnsspem.so
-rwxr-xr-x 1 root root 13312 Mar 8 11:30 lib64/libnsssysinit.so
-rwxr-xr-x 1 root root 229152 Mar 8 11:30 lib64/libnssutil3.so
-rwxr-xr-x 1 root root 23664 Mar 8 11:30 lib64/libplc4.so
...

# unpack
$ file gunzip initrd.img.gz
initrd.img: gzip compressed data, from Unix, last modified: Wed Mar 8 11:30:10 2023, max compression
$ gunzip initrd.img.gz

$ cpio -idv < initrd.img
bin/ dev/ init kdump_tools/ lib/ lib64/ proc/ sbin/ sys/ usr/

Check if Hard Drive is SSD or HDD on Linux

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 1 for HDD, 0 for SSD
################ way1=======================
$ cat /sys/block/sda/queue/rotational
1
################ way2=======================
$ lsblk -d -o name,rota
NAME ROTA
sda 1
...
sdm 0
nvme0n1 0
################ way3=======================
$ smartctl -a /dev/sda | grep 'Rotation Rate'
Rotation Rate: 7200 rpm
$ smartctl -a /dev/sdm | grep 'Rotation Rate'
Rotation Rate: Solid State Device
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# show filesystem, uuid etc for block device
$blkid
/dev/sda1: UUID="5cf26576-d3d1-48d1-aab4-1326cdda3c77" TYPE="xfs"
/dev/sda2: UUID="mFfzPH-yRAk-6ASm-6ASF-Nizr-9u3m-25wQgr" TYPE="LVM2_member"
/dev/mapper/centos_dev-root: UUID="6b5ed230-86e5-4ab6-9e96-08caf90afca6" TYPE="xfs"
/dev/mapper/centos_dev-swap: UUID="638cc56c-e2c9-425a-b13a-0c890082db1b" TYPE="swap"
/dev/mapper/centos_dev-home: UUID="cab6c113-6e6d-4d9a-8654-eb304b9100c3" TYPE="xfs"
/dev/mapper/centos_dev-var: UUID="7aafa462-85af-4587-a334-beeb477e25f6" TYPE="xfs"

$lsblk -f
NAME FSTYPE LABEL UUID MOUNTPOINT
sda
├─sda1 xfs 5cf26576-d3d1-48d1-aab4-1326cdda3c77 /boot
└─sda2 LVM2_member mFfzPH-yRAk-6ASm-6ASF-Nizr-9u3m-25wQgr
├─centos_dev-root xfs 6b5ed230-86e5-4ab6-9e96-08caf90afca6 /
├─centos_dev-swap swap 638cc56c-e2c9-425a-b13a-0c890082db1b [SWAP]
├─centos_dev-home xfs cab6c113-6e6d-4d9a-8654-eb304b9100c3 /home
└─centos_dev-var xfs 7aafa462-85af-4587-a334-beeb477e25f6 /var
$df -Th
Filesystem Type Size Used Avail Use% Mounted on
devtmpfs devtmpfs 16G 0 16G 0% /dev
tmpfs tmpfs 16G 0 16G 0% /dev/shm
tmpfs tmpfs 16G 888K 16G 1% /run
tmpfs tmpfs 16G 0 16G 0% /sys/fs/cgroup
/dev/mapper/centos_dev-root xfs 100G 45G 56G 45% /
/dev/sda1 xfs 297M 191M 107M 65% /boot
/dev/mapper/centos_dev-var xfs 50G 9.4G 41G 19% /var
/dev/mapper/centos_dev-home xfs 300G 58G 243G 20% /home
overlay overlay 50G 9.4G 41G 19% /var/lib/docker/overlay2/5c1f012f94cc69c18a9fbcc84c5403232f103c6a68b9544ba2284f59ee99e379/merged
tmpfs tmpfs 3.2G 876K 3.2G 1% /run/user/0

# disk error hence disk mounted as read-only fix it by
$ fsck -aC
OR
$ e2fsck -f -y -v /dev/sda1
then
$ reboot

$ df -lh # show disk partition
$ df -ih # show inode free/used

$ du -h -d 1 # show file size

# format disk with ext2 or ext3 etc
# mkfs.bfs mkfs.cramfs mkfs.ext2 mkfs.ext3 mkfs.ext4 mkfs.ext4dev mkfs.minix mkfs.msdos mkfs.ntfs mkfs.vfat

$ fdisk -l
$ mkfs.minix /dev/sdb1

# increase /tmp size by remounting it with a large file

$ dd if=/dev/zero of=/usr/temp-disk bs=2M count=1024
$ mkfs.ext3 /usr/temp-disk

# add /etc/fstab file with below content
/usr/temp-disk /tmp ext3 rw,noexec,nosuid,loop 0 0

UUID vs PARTUUID

  • UUID is a filesystem-level UUID, which is retrieved from the filesystem metadata inside the partition. It can only be read if the filesystem type is known and readable.
  • PARTUUID is a partition-table-level UUID for the partition, a standard feature for all partitions on GPT-partitioned disks. Since it is retrieved from the partition table, it is accessible without making any assumptions at all about the actual contents of the partition.
1
2
3
4
5
6
7
8
9
10
11
12
$ls /dev/disk/by-uuid/
38db244b-e0b7-45fb-aftg-a168b6fd00fd 433acdf3-70b7-4e93-abcd-04817a6aeae1
$ls /dev/disk/by-partuuid/
0260d409-b765-4de2-adfd-493e92087395 7d05dd0b-ab8a-48eb-12ad-2ef4e4e8b3af ...

# uuid is return if this partition has a filesystem
$blkid /dev/sdm1
/dev/sdm1: UUID="38db244b-e0b7-34fb-adbd-a168b6fd00fd" TYPE="xfs"

# partuuid is return if no filesytem on it
$blkid /dev/sdl1
/dev/sdl1: PARTLABEL="meta" PARTUUID="87a0bfbf-2374-4be8-93c7-b5d49810ee9b"

regular pattern greedy vs lazy match

'Greedy' means match longest possible string. while 'Lazy' or non-greedy means match shortest possible string.

Greedy quantifier Lazy quantifier Description
* *? Star Quantifier: 0 or more
+ +? Plus Quantifier: 1 or more
? ?? Optional Quantifier: 0 or 1
{n} {n}? Quantifier: exactly n
{n,} {n,}? Quantifier: n or more
{n,m} {n,m}? Quantifier: between n and m
1
2
3
4
# grep with lazy match
# egrep does not support non-greedy matching. Using perl mode -P will help you:
# -o only print the matched part!!!
$grep -o -P 'https.*?mp3' example.txt | sort | uniq

tar with progress bar

1
2
$D=".//dir1 ./file1"
$tar pcf - $D | pv -s "$(du -sk --total $D | tail -n1 | cut -f1)k"| gzip > target.tar.gz

control file for sudo

The /etc/sudoers file is a critical configuration file on Unix-like operating systems, including Linux, that controls the permissions for users to execute commands with superuser (root) privileges using the sudo command. Here are the key aspects of the /etc/sudoers file:

  • Access Control: The primary function of the /etc/sudoers file is to define which users or groups can execute specific commands as the root user or another user. This allows for fine-grained control over administrative privileges without giving users full root access.
  • Defaults and Aliases: The file can also contain default settings and aliases to simplify configuration. Aliases can be defined for users, hosts, commands, and run-as specifications to group multiple entries togethe

By default sudo inherits ENV and PATH from users, but it should be reset by /etc/sudoers to prevent the use of potentially harmful variables and allow only trusted directories are used for command execution, so that user should set Defaults env_reset and Defaults env_reset at /etc/sudoers file

1
2
3
4
5
6
7
8
9
10
11
$ sudo cat /etc/sudoers
...
Defaults env_reset
Defaults env_keep = "COLORS DISPLAY HOSTNAME HISTSIZE KDEDIR LS_COLORS"
Defaults env_keep += "MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE"
Defaults env_keep += "LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES"
Defaults env_keep += "LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE"
Defaults env_keep += "LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY"

Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin"
...

what does dmesg do

dmesg is used to examine or control the kernel ring buffer, so that after each reboot, it’s fresh!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
$ dmesg
[ 0.000000] Linux version 4.14.15-1.el7.elrepo.x86_64 (mockbuild@Build64R7) (gcc version 4.8.5 20150623 (Red Hat 4.8.5-16) (GCC)) #1 SMP Tue Jan 23 20:28:26 EST 2018
[ 0.000000] Command line: BOOT_IMAGE=/vmlinuz-4.14.15-1.el7.elrepo.x86_64 root=UUID=d94e304b-6b86-4a2b-8016-4029b94f92cc ro crashkernel=auto modprobe.blacklist=mlx5_core,virtio_pci hugepages=800 intel_iommu=on processor.max_cstate=1 idle=poll intel_pstate=disable pci=realloc
[ 0.000000] x86/fpu: Supporting XSAVE feature 0x001: 'x87 floating point registers'
[ 0.000000] x86/fpu: Supporting XSAVE feature 0x002: 'SSE registers'
[ 0.000000] x86/fpu: Supporting XSAVE feature 0x004: 'AVX registers'
[ 0.000000] x86/fpu: xstate_offset[2]: 576, xstate_sizes[2]: 256
[ 0.000000] x86/fpu: Enabled xstate features 0x7, context size is 832 bytes, using 'standard' format.
[ 0.000000] e820: BIOS-provided physical RAM map:
[ 0.000000] BIOS-e820: [mem 0x0000000000000000-0x0000000000099bff] usable

# show timestamp and color import thing
$ dmesg -TL
[Wed Aug 21 19:49:14 2024] Linux version 4.14.15-1.el7.elrepo.x86_64 (mockbuild@Build64R7) (gcc version 4.8.5 20150623 (Red Hat 4.8.5-16) (GCC)) #1 SMP Tue Jan 23 20:28:26 EST 2018
[Wed Aug 21 19:49:14 2024] Command line: BOOT_IMAGE=/vmlinuz-4.14.15-1.el7.elrepo.x86_64 root=UUID=d94e304b-6b86-4a2b-8016-4029b94f92cc ro crashkernel=auto modprobe.blacklist=mlx5_core,virtio_pci hugepages=800 intel_iommu=on processor.max_cstate=1 idle=poll intel_pstate=disable pci=realloc
[Wed Aug 21 19:49:14 2024] x86/fpu: Supporting XSAVE feature 0x001: 'x87 floating point registers'
[Wed Aug 21 19:49:14 2024] x86/fpu: Supporting XSAVE feature 0x002: 'SSE registers'
[Wed Aug 21 19:49:14 2024] x86/fpu: Supporting XSAVE feature 0x004: 'AVX registers'
[Wed Aug 21 19:49:14 2024] x86/fpu: xstate_offset[2]: 576, xstate_sizes[2]: 256
[Wed Aug 21 19:49:14 2024] x86/fpu: Enabled xstate features 0x7, context size is 832 bytes, using 'standard' format.
[Wed Aug 21 19:49:14 2024] e820: BIOS-provided physical RAM map:
[Wed Aug 21 19:49:14 2024] BIOS-e820: [mem 0x0000000000000000-0x0000000000099bff] usable

temporary select next reboot kernel

If you want to temporarily boot a different entry just once, you can use the grub-reboot command before rebooting.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# ----------------- temporary only once ----------------------
# menu index starts from 0
$ sudo grub-reboot 2
# OR
$ sudo grub2-reboot 2

$ sudo reboot

# 1>2: main menu index: 1, submenu index: 2
$ sudo grub-reboot "1>2"
# OR
$ sudo grub2-reboot "1>2"

$ sudo reboot


# ----------------- permanently---------------------
# show all boot indexes
$ sudo grubby --info=ALL

# Locate the GRUB_DEFAULT line and set it to the desired index number or menu entry name
$ sudo vi /etc/default/grub

# update grub
$ sudo grub2-mkconfig -o /boot/grub2/grub.cfg
$ reboot