Ubuntu 杂记

日常命令

解压到指定目录

tar 用 -C 参数, unzip 用 -d 参数

time 命令

  • 系统内建 time 命令,shell 有另一个 /usr/bin/time,默认执行前者
  • 输出运行时间到文件用 -o 参数

nohup

ssh 连接退出时会话关闭,之前会话所打开的进程会收到 SIGHUP 信号,有些程序会因此关闭。而我所遇到的后台程序多是选择无视 : - ) ,但是遇到 ssh 非正常退出,这些后台程序也因此关闭 : - ( 。保险起见,使用 nohup 。

ps aux

显示所有运行进程

sshpass

ssh 命令行直接输入密码

last 与 lastb

分别查看登陆与登陆失败记录

update-alternatives 命令切换

1
update-alternatives --config cmd # 查看命令切换配置

uname

  • -a 查看内核版本,所有信息
  • -m 查看系统位数

ssh-keygen -t rsa

生成 ssh 密钥对

输出到屏幕及文件

1
2
echo 'hello world' 2>&1 | tee log.txt
echo 'hello world' |& tee log.txt # bash version 4

ssh连接测试

1
ssh -T git@git.oschina.net

解压目录下所有zip文件

1
for f in *.zip; do unzip $f; done

shell

变量可见性 + source + export

  • shell 变量是默认只对本 shell 可见
  • 使用 export 命令可以使变量对子 shell 可见,但仅以复制(传值)形式
  • source(同“.”): 在当前 shell 执行脚本,不开启子 shell

所以,如果需使脚本变量对当前 shell 及子 shell 可见,需要结合 source 和 export

while + 文件 + 字符串分割

1
2
3
4
5
6
7
8
9
10
11
#!/bin/bash
# 从 $in 文件读入用“,”分割的行,将每行前2个域输出到 $out 文件
OLD_IFS="$IFS"
IFS="," # 内部域分隔符 (Internal Field Seprator),默认为空白符,这里设置为 “,”
while read line # 按行读入
do
arr=($line) # 分割行,存入 arr 数组
echo ${arr[0]} # 输出第0个元素
echo ${arr[1]}
done < $in > $out # 从$in文件读入,从$out文件输出
IFS="$OLD_IFS" # 恢复默认

运行脚本

  • 脚本运行前即读入所有命令,即使删除也正常运行

case 语句

1
2
3
4
5
6
7
8
9
10
11
12
# case 语句示例
case "$1" in
start) # 匹配字符串
echo start
;; # break
stop)
echo stop
;; # break
*)
echo "Usage: test start|stop"
;;
esac

读入参数

1
2
3
4
5
6
7
# ask to suspend system, if so, request for password
read -p "suspend system? (yes/no): " cmd
if [ "$cmd" = "yes" ]
then
read -s -p "sudo needed, please enter passwd: " pswd
echo $pswd | sudo -S pm-suspend-hybrid # 挂起休眠混合模式,挂起数据存入 ram,休眠存入 disk
fi

日常操作

防止某软件自动更新

1
2
3
nvidia-smi # 查看驱动版本
dpkg --get-selections nvidia*
sudo apt-mark hold nvidia-375

打开终端中文乱码

ctrl+alt+f1打开终端,中文乱码。

  • 解决方案一:用支持中文的终端通过ssh连接
  • 解决方案二:使用fbterm,参考博文
    1
    2
    3
    4
    5
    6
    # 安装
    sudo apt install fbterm
    # 使用
    sudo fbterm
    # 退出
    exit

监视磁盘运行

1
2
3
4
5
6
7
8
9
sudo iotop    # 查看读写速度(包括各进程)

# 安装 apt-get install sysstat
# 最后一列为CPU时间占用率,反应繁忙程度
iostat -dx 1

lsblk # 查看各磁盘容量

pydf # 查看磁盘容量及使用率

安装中文输入法

1
2
sudo apt-get install fcitx-table-wbpy
# 重启系统

apt update使用代理

1
2
3
export http_proxy="http://hostname:port"
export ftp_proxy="http://hostname:port"
sudo apt-get update

安装chrome

1
2
3
4
5
cd /tmp
wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
sudo dpkg -i google-chrome-stable_current_amd64.deb
# 如果软件依赖报错,执行
sudo apt-get -f install

chrome 带socks5启动

1
2
3
google-chrome --proxy-server="socks5://addr_ip:port"
# addr_ip:port 为代理ip及端口,如,localhost:1080
# 如果 chrome 已装代理插件,如 SwitchyOmega,选择使用系统代理

交换区增删

交换区可以视作一个文件。运用命令:mkswap 格式化文件,swapon 启动交换区, swapoff 撤销交换区(不删除)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 创建 1GB 的文件,bs一次传输字节数, count 传输次数
# 文件大小=bs * count 字节,1K=1024, 1M=1K*1K, 1G=1M*1K
sudo dd if=/dev/zero of=/swapfile bs=1K count=1M
# 设置文件权限
sudo chown root:root /swapfile
sudo chmod 0600 /swapfile

sudo mkswap /swapfile # 格式化
sudo swapon /swapfile # 激活

# 设置开机自动挂载
sudo vi /etc/fstab # 编辑,添加以下配置
##################添加内容
/swapfile none swap sw 0 0
##################

########### 撤销交换区 ###########
sudo swapoff /swapoff
sudo vi /etc/fstab # 编辑,删除以下配置
##################删除内容
/swapfile none swap sw 0 0
##################
sudo rm /swapfile # 可删除文件

挂载新硬盘

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 查看硬盘使用情况
df -h
# 用下面两条命令找到新的硬盘,比如/dev/sdb
lsblk
sudo fdisk -l
# 格式化硬盘
sudo mkfs -t ext4 /dev/sdb
# 可选,设置卷标,比如home2nd
# 查看UUID,比如0943c0ae-8a25-45c0-b4c4-08b76baa73d3
sudo blkid
sudo e2label /dev/sdb home2nd
# 创建挂载目录
sudo mkdir /home2nd
# 编辑 /etc/fstab,加入:
UUID=0943c0ae-8a25-45c0-b4c4-08b76baa73d3 /home2nd ext4 defaults 0 0

sudo reboot

ssh 无密码登陆

1
2
3
ssh-keygen -t rsa # 生成密钥,如果已生成可跳过
ssh-copy-id user@server_addr # 将密钥推送到服务器
ssh ssh_rtunnel@server_B_addr # 检验能否成功无密码登陆

增删用户

添加用户

1
2
3
4
5
6
7
8
sudo adduser <username> #添加一个普通用户
# useradd 是相对底层的命令
# sudo useradd -s /bin/bash -m <username> #-m 创建主目录
sudo usermod -aG <usergroup> username
# 可选将用户加入用户组,如 sudo组,可能需要logout再login生效
# 下面的命令起同样的效果
# sudo adduser <username> <usergroup>
# sudo passwd <username> # 初始化或修改用户密码

修改已添加用户的shell

1
sudo usermod -s /bin/bash user # 修改已添加用户的shell为 bash

使用户能够在登陆屏登陆,在 /etc/lightdm/lightdm.conf加入:

1
2
[SeatDefaults]
greeter-show-manual-login=true

删除用户:

1
2
sudo deluser <username>
sudo rm -r /home/<username>

切换用户主目录

  • 修改/etc/passwd
  • mv 主目录

主目录下的文件夹名改回英文

1
2
export LANG=en_US
xdg-user-dirs-gtk-update

之后注销。参考中文Ubuntu主目录下的文档文件夹改回英文

ssh 反向 tunnel

两台主机,局域网主机LAN A,拥有公网IP主机SERVER B,建立反向 tunnel,从外网通过B访问A。

第一步:在SERVER B创建用户,并实现A无密码登陆B,详见“增删用户”及“ssh 无密码登陆”部分。

1
2
3
4
5
6
7
8
9
10
11
# login SERVER B
sudo useradd -m ssh_rtunnel # 添加一个普通用户 ssh_rtunnel
sudo passwd ssh_rtunnel # 初始化密码
###################################################
# login LAN A
ssh-keygen -t rsa # 生成密钥,如果已生成可跳过
ssh-copy-id ssh_rtunnel@server_B_addr # 将密钥推送到SERVER B
ssh ssh_rtunnel@server_B_addr # 检验能否成功无密码登陆
###################################################
# login SERVER B
sudo usermod -s /bin/false ssh_rtunnel # 防止 ssh_rtunnel 执行 shell 命令

第二步:SERVER B配置

1
2
3
4
5
6
7
# login SERVER B
sudo vi /etc/ssh/sshd_config # 向 sshd_config 文件添加:
##################添加内容
GatewayPorts clientspecified
##################

sudo service sshd restart # 重启 ssh 服务

第三步:LAN A创建 tunnel

1
2
3
4
5
6
# login LAN A
sudo apt-get install autossh
autossh -fN -R :2210:localhost:22 ssh_rtunnel@server_B_addr
# 创建 tunnel。SERVER B在2210端口收到的数据都会传向LAN A的22号端口
# 由于 22 号端口是 ssh 连接端口,故该 tunnel 可用于 ssh 连接
# 可将这条命令加入 /etc/profile 使之开机自启

最后可在任何能访问到SERVER B的主机上访问LAN A

1
ssh -p 2210 user_on_LAN_A@server_B_addr

检查进程是否运行

1
2
3
4
5
6
7
8
9
10
11
12
if ! ps -p $PID > /dev/null # 如果进程不存在
then
echo not runnig
fi

# 每8秒检查一次进程是否结束
while ps -p $PID > /dev/null # 如果进程存在
do
sleep 8
done
# 进程已结束
echo not runnig

查看父进程ID

1
2
3
4
ps -o ppid= 1 # 查看1号进程父进程,注意空格
ps -f 1 # 详细信息
pstree -p 1 | less # 查看1号进程的子进程树。用less分页显示
pstree -s -p 1 # 同时查看父进程

Nvidia显卡信息

1
2
3
4
5
6
nvidia-smi
# 查询gpu指定信息,用逗号分隔,这里查看已用显存大小(M)
nvidia-smi --format=csv,noheader,nounits --query-gpu=memory.used
nvidia-smi --format=csv --query-gpu=power.draw,utilization.gpu,fan.speed,temperature.gpu
# 更多查询选项
nvidia-smi --help-query-gpu

查看硬件信息

1
2
3
4
5
6
sudo lshw # 所有硬件信息
sudo lshw -C cpu # cpu 信息
sudo lshw -C memory # 内在信息
sudo lshw -C display # 显卡信息
nvidia-smi -q # nvidia 显卡信息
sudo lshw -C storage # 硬盘信息

文本换行符转换

  • todos, fromdos 命令
  • vi 编辑器命令:
    1
    2
    :set fileformat=dos
    :set fileformat=unix

压缩包中文文件名乱码

解压,解决方式一:

1
unzip -O CP936 zipfile

解压,解决方式二, 在 ubuntu 文件区内

1
2
LANG=C 7z x CompressedFile
convmv -f GBK -t UTF8 CompressedFile --notest

压缩,使用 7z 命令压缩。

防暴力登陆盗取密码

  • 使用 last 与 lastb 检查最近登陆情况
  • denyhosts 工具防 ssh 猜测密码
denyhosts 安装
1
2
3
4
5
6
7
8
9
10
11
12
sudo apt-get install denyhosts  # denyhosts 不同版本配置有差别
sudo vi /etc/denyhosts.conf # 可选配置 denyhosts
# RESET_ON_SUCCESS = yes # 如果登录成功,重置计数
# DEVY_THRESHOLD_INVALID = 5 # 允许无效用户登录失败次数
# DEVY_THRESHOLD_VALID = 10
# DEVY_THRESHOLD_ROOT = 1
# DEVY_THRESHOLD_RESTRICTED = 1
sudo service denyhosts start # 运行

ls /etc/rc2.d | grep denyhosts # 如果有输出,证明安装程序已经设置开机自启

vi /etc/hosts.deny # 一段时间后可查看被禁 ip

如果自己 ip 被屏蔽了,可以换个 ip 登陆,再参考 删除 DenyHosts 屏蔽 ip 方法,其中 WORK_DIR 可能为 /var/lib/denyhosts

本机端口转发

1
2
3
4
5
6
7
8
9
10
sudo vi /etc/sysctl.conf
# 添加下句
# net.ipv4.ip_forward=1
sudo sysctl -p
sudo iptables -t nat -A PREROUTING -d 本机IP -p tcp --dport 源端口 -j DNAT --to-destination 本机IP:目的端口
sudo vi /etc/rc.local
# 将命令写入,实现开机启动
# iptables -t nat -A PREROUTING -d 本机IP -p tcp --dport 源端口 -j DNAT --to-destination 本机IP:目的端口
# 用此命令查看nat列表
sudo iptables -t nat --list

发送邮件

用 heirloom-mailx 工具

heirloom-mailx 安装
1
2
3
4
5
6
7
8
9
10
11
12
sudo apt-get install heirloom-mailx
sudo vi /etc/nail.rc # 必须配置发送账号及其 stmp 服务器
###############配置
set from=USER@163.com
set smtp=smtp.163.com
set smtp-auth-user=USER
set smtp-auth-password=PASSWORD
set smtp-auth=login
###############

# 发送邮件
echo "邮件内容" | heirloom-mailx -s "邮件标题" toWho@email.address

安装配置网络代理——shadowsocks

服务器端

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
sudo apt-get install python-pip
sudo pip install shadowsocks # 安装 shadowsocks

sudo vi /etc/shadowsocks.conf # 编辑配置文件
###############配置
{
"server":"server ip",
"server_port":8388,
"local_port":1080,
"password":"your password",
"timeout":600,
"method":"aes-256-cfb"
}
###############

# 启动
sudo /usr/local/bin/ssserver -v --log-file /var/log/shadowsocks.log -c /etc/shadowsocks.conf -d start

sudo vi /etc/rc.local # 加入以下命令以开机自启
###############配置
/usr/local/bin/ssserver -v --log-file /var/log/shadowsocks.log -c /etc/shadowsocks.conf -d start
###############

vi /var/log/shadowsocks.log # 可查看运行日志

主页下可以找到 windows 客户端下载android 客户端下载

Ubuntu 客户端:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
sudo apt-get install python-pip
sudo pip install shadowsocks # 安装 shadowsocks

vi ~/.shadowsocks.conf # 编辑配置文件
###############配置
{
"server":"server ip",
"server_port":8388,
"local_port":1080,
"password":"your password",
"timeout":600,
"method":"aes-256-cfb"
}
###############

nohup sslocal -c ~/.shadowsocks.conf &>/dev/null & # 启动,可将输出重定向作为日志
vi ~/.profile # 开机自启,加入下列命令
###############配置
nohup sslocal -c ~/.shadowsocks.conf &>/dev/null &
###############

Ubuntu图形客户端

1
2
3
4
5
sudo add-apt-repository ppa:hzwhuang/ss-qt5
sudo apt-get update
sudo apt-get install shadowsocks-qt5
# 启动
ss-qt5

文件处理之 sed

参考网页:远有青山——Sed 命令详解 正则表达式元字符 东方雨中漫步者——linux之sed用法学习 进步——linux sed命令详解

sed [选项] [输入文件]

常用选项:

  • -i 直接修改读取的档案内容
  • -n 使用安静(silent)模式。在一般sed的用法中,所有来自STDIN的资料一般都会被列出到萤幕上。但如果加上-n参数后,则只有经过sed特殊处理的那一行才会被列出来。

常用命令:

  • s:字符串替换
  • p: 打印

元字符:

  • $:行尾或最后一行
  • ^: 行开头
1
2
sed -i '$s/./a/1' file.txt # 最后一行第一个字符替换为 'a'
sed -n "/^root$/p" file.txt # 打印内容为root的行

rc.local开机启动脚本

首先检测是否支持rc.local

1
2
sudo systemctl start rc-local.service
sudo systemctl status rc-local.service

参考:https://www.claudiokuenzler.com/blog/783/ubuntu-18.04-rc.local-file-not-exist-launch-with-systemd-rc-local

在新版的Ubuntu中默认不支持rc.local开机执行,可在/etc/init.d下加入rc.local脚本以支持。

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
#! /bin/sh
### BEGIN INIT INFO
# Provides: rc.local
# Required-Start: $all
# Required-Stop:
# Default-Start: 2 3 4 5
# Default-Stop:
# Short-Description: Run /etc/rc.local if it exist
### END INIT INFO


PATH=/sbin:/usr/sbin:/bin:/usr/bin

do_start() {
if [ -x /etc/rc.local ]; then
/etc/rc.local
return $?
fi
}

case "$1" in
start)
do_start
;;
restart|reload|force-reload)
echo "Error: argument '$1' not supported" >&2
exit 3
;;
stop|status)
# No-op
exit 0
;;
*)
echo "Usage: $0 start|stop" >&2
exit 3
;;
esac

执行以下命令:

1
2
3
4
sudo chown root:root /etc/init.d/rc.local
sudo chmod 755 /etc/init.d/rc.local
cd /etc/init.d
sudo update-rc.d rc.local defaults 99

随后可编辑/etc/rc.local脚本,注意权限755,用户为root。注:/etc/rc.local首行加#!/bin/bash

1
2
sudo chown root:root /etc/rc.local
sudo chmod 755 /etc/rc.local

参考文档:

文件

/etc/network/if-up.d 目录

网络建立后会执行其下脚本

/usr/local 与 /opt

两者都是手动(非 apt)安装程序目录,当然都需要 root 权限。不同在于,/usr/local 下有 bin, src, include 之类目录,程序各部分分家,遵从系统程序安装习惯,而 /opt 就没有这个约束,所以,像 Tomcat 这种拥有自己目录结构的程序应该置于 /opt 下,并且拥有独立的目录,如 /opt/tomcat。

/etc/rc#.d

目录,# 是数字,代表运行级别。其下有多个脚本,多是 /etc/init.d 目录下脚本的链接,在转换到相应运行级别时按序执行,如 init 0,会执行 rc0.d 下脚本。文件命名以 K, S 开头,分别表示关闭、开启服务。

/etc/rc.local

开机后系统自动执行的脚本

/etc/init.d

存放各种管理服务——如 mysql——的脚本的目录。可以用 service 命令调用这些脚本以执行服务的启动关闭等操作,当然也可直接执行,如

1
2
sudo service mysql status
sudo /etc/init.d/mysql status

/etc/issue

系统发布版本

/proc/cpuinfo

cpu 信息。processor 逻辑 cpu 编号,总计为 cpu 线程数,physical id 物理 cpu 编号,总计为 cpu 个数,core id 为 cpu 的(对应某cpu的)核心编号,总计为 cpu 核心数。机器可有多个 cpu,每个 cpu 可有多个核心,每个核心可以开多个线程。

/proc/meminfo

内存信息。也可用 free 命令查看内存

常识

运行级别

  1. 关机
  2. 单用户,Does not configure network interfaces, start daemons, or allow non-root logins
  3. 多用户,无网络连接 Does not configure network interfaces or start daemons
  4. 多用户,启动网络连接,仅启动命令行界面 Starts the system normally.
  5. 用户自定义
  6. 多用户,带图形界面
  7. 重启

摘自wikipedia, 在Debian Linux中,2-5这四个运行级别合为多用户状态,默认2。可用 init 命令切换运行状态。