Linux 环境实用工具

Linux 下工作常用工具,用于提升效率。

蓝牙

1
2
3
4
5
6
7
8
9
10
bluetoothctl
[bluetooth]# power off
[bluetooth]# power on
[bluetooth]# scan on
[bluetooth]# connect XX:XX:XX:XX:XX:XX
[Arc Touch Mouse SE]# trust
[Arc Touch Mouse SE]# pair
[Arc Touch Mouse SE]# unblock
[Arc Touch Mouse SE]# power off
[bluetooth]# power on

比如我想连自己的蓝牙键盘,scan on后会打印出来一堆搜到的蓝牙设备,其中可以看到自己的蓝牙键盘:

1
2
[CHG] Device 90:7F:61:56:8A:CE Name: ThinkPad Multi Connect Bluetooth Keyboard with Trackpoint
[CHG] Device 90:7F:61:56:8A:CE Alias: ThinkPad Multi Connect Bluetooth Keyboard with Trackpoint

wxwork(企业微信)

https://blog.csdn.net/weixin_32087115/article/details/85261860
创建一个执行脚本:

1
2
nohup /usr/lib/gnome-settings-daemon/gsd-xsettings > /dev/null 2>&1 &
/opt/deepinwine/apps/Deepin-WXWork/run.sh

wget

wget 命令用于在终端中下载网络文件,格式为:wget [参数] 下载地址

参数 作用
-b 后台下载模式。
-O 下载到指定目录。
-t 最大尝试次数。
-c 断点续传
-p 下载页面内所有资源,包括图片、视频等。
-r 递归下载
1
2
# 递归下载网站所有页面和图片等资料
wget -r -p http://www.baidu.com

简单系统维护

reboot

重启计算机这种操作涉及到对硬件资源的管理权限,因此默认只能使用 root 用户来调用:

1
$ reboot

poweroff

关机命令也同理,只有 root 用户才能关闭电脑:

1
$ poweroff

uname

查看系统内核与系统版本等信息
一般我们会固定搭配上-a 参数来完整查看当前系统的信息,包括内核名称、主机名、内核发行版本、节点名、系统时间、硬件名称、硬件平台、处理器类型以及操作系统名称等

1
2
3
4
root@dm-slave-slave:~# uname
Linux
root@dm-slave-slave:~# uname -a
Linux dm-slave-slave 4.4.0-105-generic #128-Ubuntu SMP Thu Dec 14 12:42:11 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux

uname 命令只能看到内核版本,如果要查看发行版的版本,可以找找 release 文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
root@dm-slave-slave:~# ls /etc/ | grep release
lsb-release
os-release
root@dm-slave-slave:~# cat /etc/os-release
NAME="Ubuntu"
VERSION="16.04.3 LTS (Xenial Xerus)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 16.04.3 LTS"
VERSION_ID="16.04"
HOME_URL="http://www.ubuntu.com/"
SUPPORT_URL="http://help.ubuntu.com/"
BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/"
VERSION_CODENAME=xenial
UBUNTU_CODENAME=xenial

sosreport

收集系统配置并诊断信息后输出结论文档
当我们的 Linux 系统出现故障需要联系红帽厂商或其他技术支持时,大多数时候都要先使用这个 SOS 功能来简单收集计算机的状态和配置信息,以便让技术支持公司能够通过远程就解决了一些小问题,又或者让他们能对复杂问题能提前有些了解

pandoc(文档格式转换)

Markdown -> PPT:https://blog.csdn.net/yyw794/article/details/73697810

Linux 控制台

unity-control-center
gnome-control-center

crontab

参考

  1. 19. crontab 定时任务

WIFI

图形界面创建 WIFI

  1. 点击有上角网络标志,点开编辑链接。
  2. 选择 WiFi ,添加一个网络。
  3. 设置这个网络 做如下编辑:
    • 编辑 wifi 的名字:SSID,
    • 选择 Hotspot (热点)模式.
    • 在 Wifi Security(wifi 安全性) 页, 选择 WPA & WPA2 Personal(WPA & WPA2 个人)选项并输入你要创建的 wifi 密码,8 位以上.
    • 在 IPv4 设置页面, 选择 “Share to other computers”(与其他计算机共享)
  4. 点击 save ,然后点击右上角网络选项中的 Connect to Hidden Wi-Fi network (连接到隐藏的 WIFI 网络),在连接选择框里,选择你刚刚创建的网络。
  5. 完成,你可以用手机等连接了

最后,如果出现“Connection ‘xxx’ is not available on the device wlp3s0 at this time”问题……
主要因为你使用了 Broadcom Corporation 网卡驱动,换过来就好了。
解决方案:系统设置–>软件和更新–>附加驱动–>将 Broadcom Corporation….那一项选择“不使用设备”–>应用更改–>重新启动

命令行连接 WIFI

http://askubuntu.com/questions/461825/connect-to-wifi-from-command-line

1
2
3
4
sudo nmcli radio wifi on # 开启wifi
nmcli dev wifi # 查看附近可用wifi
nmcli c up NEU # 连接
nmcli c down NEU # 断开

tmux

1.安装
2.在~目录下创建文件.tmux.conf

1
2
3
4
5
6
setw -g c0-change-trigger 100
setw -g c0-change-interval 250

bind-key c new-window -c "#{pane_current_path}"
bind-key % split-window -h -c "#{pane_current_path}"
bind-key '"' split-window -c "#{pane_current_path}"

3.打开

1
tmux

4.操作
下面命令前面必须加上 ctrl+b
session 操作:

1
2
3
s 查看/切换session  
d 离开Session
$ 重命名当前Session

window 操作:

1
2
3
4
c 新建窗口
space 切换到上一个活动的窗口
& 关闭一个窗口
窗口号 使用窗口号切换

pane 操作:

1
2
3
4
5
6
o 切换到下一个窗格
q 查看所有窗格的编号
" 水平拆分出一个新窗格
% 垂直拆分出一个新窗格
z 暂时把一个窗体放到最大
x 删除一个窗格

参考

  1. 优雅地使用命令行:Tmux 终端复用

i3wm

配置 i3

/etc/i3/config
~/.config/i3/config

参考

  1. 使用
    ubuntu+i3wm 桌面
    debian 使用 i3 教程:从 0 开始
    安装使用 i3wm 窗口管理器
    如何配置 linux 平铺式窗口管理器 i3wm?
  2. 配置
    oh-my-i3
    Linux 桌面平铺管理器 - i3wm
    i3
  3. 小控件
    配置文件为/etc/i3status
    (选用 pnmixer)i3wm 音量控制挂件有哪些?
    (选用 arandr)i3-wm 设置多屏显示
    温度:查看 man i3status 搜索“CPU-Temperature”即可得到温度设置方法

gdb

编译

1
gcc main.c -g -Wall -Werror -o main

其中-g 选项生成调试用的符号表,-Wall 显示所有 warning,-Werror 使得 warning 变成 error。

运行 gdb

断点检查

1
2
3
4
list
break 5
run
continue

单步

next 总是保持在当前 scope 下

1
2
3
4
5
list
break 5
run
next
step将进入每个scope

检查变量

1
2
3
print a
set var a = 10
watch a

检查段错误和指针问题

1.段错误:访问了未分配的地址。
2.常见原因

  • 对 NULL 解引用;
  • 对未分配的指针解引用;
  • 对已释放的指针解引用;
  • 数组访问越界,并进行了写操作;
  • 函数无限递归,占用了所有的栈空间。
    3.调试
    使用 gdb 工具加载 core 文件,打印变量值找错。
    1
    2
    3
    4
    gcc -g -Wall -Werror main.c -o main # 编译时加上-g选项
    gdb main core # 使用core文件加载
    run # gdb将会在发生段错误的位置停下
    print x # 打印可能引起错误的指针值
    4.库函数调试
    使用 backtrace 命令回溯找错
    1
    2
    3
    backtrace # 列出函数调用栈
    up # 回到上一个调用frame
    print x # 打印可能出错的变量
    注意:
  • 检查 malloc 的返回值,内存分配失败会返回 NULL;
  • 检查自定义的内存分配函数的返回值,比如 Stack_new,理由同上;
    5.解引用未初始化(局部)指针
    有以下三个策略
  • 注意将它们都初始化为 NULL 或直接分配一块内存;
  • 调试时检查指针之间的值是否接近,因为未初始化的局部变量会保存一个垃圾值;
  • 使用 gdb 打印命令
    1
    print *x # 若不是正确的地址将打印错误信息
    6.解引用已释放内存
  • 释放后立刻将指针赋值 NULL,转换为 5 的问题;
  • 不要返回局部变量的地址
    7.写操作超出数组范围
  • 如果是局部数组,写超出范围将直接 segfault;
  • 如果是分配的数组,可能不会立刻 segfault,可以关掉随机数种子,并使用 watch 命令跟踪变量
    8.stack overflows
  • 使用 backtrace,如果发现一个函数被大量调用,可能这个函数中的递归的终止条件不对。

参考

  1. A GDB Tutorial with Examples

valgrind

安装

1
sudo apt-get install valgrind

内存泄露

内存泄露问题不容易被检测,因为它不会在运行时产生明显的反应,除了内存空间用完后再调用 malloc 会发生失败。

编译

1
gcc -g main.c -o main

加上-g 选项是为了保存符号表,供之后 valgrind 定位错误用。

运行 valgrind

1
valgrind --tool=memcheck ./main

如果 alloc 数和 free 数不相等,说明发生了内存泄露。
加上 leak-check 选项
显示所有没有被释放(free)的内存分配(malloc/new/etc)调用,

1
valgrind --tool=memcheck --leak-check=yes ./main

加上–show-reachable=yes 可以显示更多未释放的内存。

找非法指针

比如对动态数组的访问超出了分配的空间

1
2
3
4
5
==23457== Invalid write of size 1
==23457==    at 0x400544: main (main.c:6)
==23457==  Address 0x520304a is 0 bytes after a block of size 10 alloc'd
==23457==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==23457==    by 0x400537: main (main.c:5)

上面的结果表明,我们企图写入一个 1 个 size 大小的对象到一个分配的空间的末尾,这个错误发生在第 6 行(main 函数中),内存块的分配是在第 5 行。

检测未初始化变量的使用

  • int a;
  • int a; foo(a); // 即将未初始化的值赋给了别的变量
    1
    2
    3
    ==23757== Conditional jump or move depends on uninitialised value(s)
    ==23757==    at 0x400531: foo (main.c:5)
    ==23757==    by 0x40054D: main (main.c:11)
    上面的结果说明,跳转语句使用了一个未初始化的变量作为条件,该变量的传递路径为 main->foo。

其他

  • 多次释放(free)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    ==23883== Invalid free() / delete / delete[] / realloc()
    ==23883==    at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
    ==23883==    by 0x4005A9: main (main.c:12)
    ==23883==  Address 0x5203040 is 0 bytes inside a block of size 4 free'd
    ==23883==    at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
    ==23883==    by 0x40059D: main (main.c:11)
    ==23883==  Block was alloc'd at
    ==23883==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
    ==23883==    by 0x40058D: main (main.c:10)
    上面结果表明,在 12 行处发生了 free 同一块内存多次的情况,且这个内存在第 10 行被分配并已在第 11 行被释放。
  • 使用了不正确的方法释放内存
    malloc()/new/new[]与 free()/delete/delete[]必须一一对应,否则报错:
    1
    Mismatched free() / delete / delete []

valgrind 的盲点

  • 不检查静态数组(栈分配)的边界
    可以选择使用动态分配替换,不过会拖慢速度。

注意事项

  • valgrind 占用大量空间;
  • valgrind 不会检查出所有错误,比如缓冲区溢出。