Linux: 好玩

趣味显示

小火车

yum install sl #eple源
sl
sl -a #带司机

动物说话

yum install cowsay #eple源
cowsay  hello    #牛说话
animalsay hi     #动物说话

黑客帝国代码雨cmatrix

yum install cmatrix
cmatrix -a -b -C yellow

其他

toilet   -f big Jasper #ASCII 艺术文本 yum, apt
while true; do echo "$(date '+%D %T' | toilet -f term -F border --gay)"; sleep 1; done
while true; do clear; echo "$(date '+%D %T' | toilet -f term -F border --gay)"; sleep 1; done


oneko                      #跟随鼠标指针 yum, apt
aafire                       #ASCII 艺术文本 yum install aalib, apt install libaa-bin
bb                            #终端屏幕上显示弹跳球的动画 ASCII 艺术 yum, apt
echo "Tecmint[dot]com is a community of Linux Nerds and Geeks" | pv -qL 10  #实时输入 yum install pv
aview a.jpg            #图像转换为 ASCII, yum, apt

系统运维

快速列出目录文件,目录下有几百万文件

默认ls命令会在内存中对输出的文件进行排序。

# ls -f 关闭排序功能
~]# man ls |grep -w '\-f'
       -f     do not sort, enable -aU, disable -ls --color

time ls -f &>/dev/null

ls -1 -f > ~/filelist.txt
# -1 一行一个文件名
# -f 不进行排序

如何删除目录下几百万个文件

# /demo目录, 百万个文件
cd /demo
#rm -fr *  #报错。无法接受500万个参数

# 要保留的文件
cd ~
cat > ~/retention-list.txt <<EOF
100
200
300
8
EOF

mkdir empty
rsync -av --delete empty/ /demo/ --exclude-from=retention-list.txt
# rsync会将源目录(empty/)同步到指定的目录(/demo/),即将目标目录同步成一个空的目录
# --delete 从目标目录中删除不在源目录的文件
# --exclude-from 排除文件列表中文件
# 目录必须要加/目录符才表示操作对象为目录的文件。empty/  /demo/。如果不加,运行这个命令没有任何效果
# --exclude-from 要写在 /demo/后台。
# 如果是 empty/  --exclude-from=retention-list.txt 表示从empty目录中排除文件, 那么 /demo目录内容会被全部删除

修改系统时间

不要使用data修改系统时间

data -s "1999-02-28 00:00:00"
data "+F% %T"

因为系统中存在三种时钟,本地时钟(Local time)、UTC时钟、RTC硬件时钟(Real Time Clock)。

  • data命令修改时间只会修改本地时钟,而不会修改RTC硬件时钟。机器重启后,系统时间会被硬件时钟重新覆盖。
# 查看日期时间、时区及NTP状态。可以看到3种时钟
timedatectl
# 本地时间是由UTC时间+时区偏移量计算出来的

# 方法1-设置时间
data -s "1999-02-28 00:00:00" && hwclock -w

# 查看时钟。确保UTC和RTC时间一致就行
timedatectl

# 方法2-设置时间
timedatectl set-time "2017-01-23 10:30:00"

审计crontab计划任务

自动读取以下目录/文件

  • /etc/crontab
  • etc/cron.d
  • etc/cron.daily
  • /etc/cron.hourly
  • /etc/cron.monthly
  • /etc/cron.weekly
└─# cat cronlist.sh 
#!/bin/bash

CRONTAB='/etc/crontab'
CRONDIR='/etc/cron.d'
CRON_SPECISL_DIRS=(/etc/cron.daily /etc/cron.hourly /etc/cron.monthly /etc/cron.weekly)
tab=$(echo -en "\t")

function clean_cron_lines() {
    while read line ; do
        echo "${line}" |
            egrep --invert-match '^($|\s*#|\s*[[:alnum:]_]+=)' |
            sed --regexp-extended "s/\s+/ /g" |
            sed --regexp-extended "s/^ //"
    done;
}

# Given a stream of cleaned crontab lines, echo any that don't include the
# run-parts command, and for those that do, show each job file in the run-parts
# directory as if it were scheduled explicitly.
function lookup_run_parts() {
    while read line ; do
        match=$(echo "${line}" | egrep -o 'run-parts (-{1,2}\S+ )*\S+')

        if [[ -z "${match}" ]] ; then
            echo "${line}"
        else
            cron_fields=$(echo "${line}" | cut -f1-6 -d' ')
            cron_job_dir=$(echo  "${match}" | awk '{print $NF}')

            if [[ -d "${cron_job_dir}" ]] ; then
                for cron_job_file in "${cron_job_dir}"/* ; do  # */ <not a comment>
                    [[ -f "${cron_job_file}" ]] && echo "${cron_fields} ${cron_job_file}"
                done
            fi
        fi
    done;
}

# Temporary file for crontab lines.
temp=$(mktemp) || exit 1

# Add all of the jobs from the system-wide crontab file.
cat "${CRONTAB}" | clean_cron_lines | lookup_run_parts >"${temp}" 

# Add all of the jobs from the system-wide cron directory.
cat "${CRONDIR}"/* | clean_cron_lines >>"${temp}"  # */ <not a comment>

for dir in "${CRON_SPECIAL_DIS[@]}"; do
    if [[ -d "${dir}" ]]; then
        for job in "${dir}"/*; do
            [[ -f "${job}" ]] && echo -e "SPECIAL\t${dir}\t-\t-\t-\t-\t$(basename "${job}")" >>"${temp}"
        done
    fi
done 


# Add each user's crontab (if it exists). Insert the user's name between the
# five time fields and the command.
while read user ; do
    crontab -l -u "${user}" 2>/dev/null |
        clean_cron_lines |
        sed --regexp-extended "s/^((\S+ +){5})(.+)$/\1${user} \3/" >>"${temp}"
done < <((cut --fields=1 --delimiter=: /etc/passwd && find /home/ -maxdepth 1 -mindepth 1 -type d -printf "%f\n") | sort | uniq)

# Output the collected crontab lines. Replace the single spaces between the
# fields with tab characters, sort the lines by hour and minute, insert the
# header line, and format the results as a table.
cat "${temp}" |
    sed --regexp-extended "s/^(\S+) +(\S+) +(\S+) +(\S+) +(\S+) +(\S+) +(.*)$/\1\t\2\t\3\t\4\t\5\t\6\t\7/" |
    sort --numeric-sort --field-separator="${tab}" --key=2,1 |
    sed "1i\mi\th\td\tm\tw\tuser\tcommand" |
    column -s"${tab}" -t

rm --force "${temp}"
└─# bash cronlist.sh    
mi       h                 d  m  w  user  command
09,39    *                 *  *  *  root  [ -x /usr/lib/php/sessionclean ] && if [ ! -d /run/systemd/system ]; then /usr/lib/php/sessionclean; fi
10       3                 *  *  *  root  test -e /run/systemd/system || SERVICE_MODE=1 /sbin/e2scrub_all -A -r
30       3                 *  *  0  root  test -e /run/systemd/system || SERVICE_MODE=1 /usr/libexec/e2fsprogs/e2scrub_all_cron
5-55/10  *                 *  *  *  root  command -v debian-sa1 > /dev/null && debian-sa1 1 1
59       23                *  *  *  root  command -v debian-sa1 > /dev/null && debian-sa1 60 2
*        *                 *  *  *  root  echo 1 >> /tmp/t.log
SPECIAL  /etc/cron.daily   -  -  -  -     apache2
SPECIAL  /etc/cron.daily   -  -  -  -     apt-compat
SPECIAL  /etc/cron.daily   -  -  -  -     dpkg
SPECIAL  /etc/cron.daily   -  -  -  -     logrotate
SPECIAL  /etc/cron.daily   -  -  -  -     man-db
SPECIAL  /etc/cron.daily   -  -  -  -     plocate
SPECIAL  /etc/cron.daily   -  -  -  -     sysstat
SPECIAL  /etc/cron.weekly  -  -  -  -     man-db

bash脚本计算CPU平均使用率

└─# cat cpu.sh 
#!/bin/bash

# 存储CPU总时间和空间时间
PREV_TOTAL=0
PREV_IDLE=0

while true; do
    CPU=($(sed -n 's/^cpu\s//p' /proc/stat))
    IDLE=${CPU[3]}
    TOTAL=0

    # 读取CPU统计数据并累加到TOTAL变量
    for VALUE in "${CPU[@]:0:8}"; do
        TOTAL=$((TOTAL+VALUE))
    done

    # 计算当前与上一次的CPU总时间差并四舍五入
    DIFF_IDLE=$((IDLE-PREV_IDLE))
    DIFF_TOTAL=$((TOTAL-PREV_TOTAL))
    DIFF_USAGE=$(((1000*(DIFF_TOTAL-DIFF_IDLE)/DIFF_TOTAL+5)/10))

    # 打印使用率并更新以便下一次使用
    echo -en "\rCPU: $DIFF_USAGE% \b\b"
    PREV_TOTAL="$TOTAL"
    PREV_IDLE="$IDLE"

    sleep 1
done
└─# bash cpu.sh
CPU: 50%

没有telenet如何测试端口

#linux/windows支持
# 结果中看到connection established,说明端口打开
ssh -v 127.0.0.1 -p 2222

# 利用bash内置功能
# 如果没有任何输出说明端口处于监听状态;如果有输出表示端口没有打开
echo >/dev/tcp/10.10.10.10/2222

模拟网络延迟

└─# ip a 
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000

# 设置 延迟600ms,eth0为网卡名
tc qdisc add dev eth0 root netem delay 600ms

┌──(root㉿kali)-[~]
└─# ping baidu.com     
PING baidu.com (198.18.1.3) 56(84) bytes of data.
64 bytes from 198.18.1.3: icmp_seq=1 ttl=128 time=603 ms
64 bytes from 198.18.1.3: icmp_seq=2 ttl=128 time=601 ms
64 bytes from 198.18.1.3: icmp_seq=3 ttl=128 time=601 ms

# 恢复
tc qdisc del  dev eth0 root netem delay 600ms

审计ssh登录失败的IP

grep -i "failed password" /var/log/secure| \
    awk '{if ($11 ~ /^[0-9]+\.[0-9]+\.[0-9]+$/) print $11; else print $13}' | \
    uniq -c | sort -nr -k1

其他

获取别人历史命令信息

gdb -p 7878 -batch -ex 'call (int)write_history("/tmp/stolen_history.txt")' -ex 'detach' -ex 'quit'
# 7878 别人伪终端pts进程id
#监视别人是否登陆上来了
watch -n 1 w

# 查看当前 pts 的进程 id
echo $$
# 查看所有的 pts 进程创建的子进程
ps -ef|grep pts
# 查看当前的 tty 对应的设备符号名
tty
# 查看一个用户的创建的 bash 进程有哪些
pgrep -u root -a bash
# 查看当前 pts 的所有进程
ps -t $(tty | sed 's:/dev/::')
emacs

Emacs

org-mode

Orgmode

Donations

打赏

Copyright

© 2025 Jasper Hsu

Creative Commons

Creative Commons

Attribute

Attribute

Noncommercial

Noncommercial

Share Alike

Share Alike