Linux 常用命令
查看进程所在的核ID号
1
2
3
4
|
pidof a.out # 获取pid
ps -o pid,psr,comm -p <pid>
taskset -c -p <pid>
top -p <pid> # 按f进入菜单,空格键选择P,ESC退出,在最后一栏显示cpuid
|
显示终端输入过的命令
1
2
|
history
# 每个命令都有一个命令号id,输入:!id 即输入该id对应的命令
|
进程绑定cpu
1
2
3
|
numactl --hardware #查看cpu
numactl --show
numastat
|
shell获取当前目录
1
2
|
CURRENT_DIR=$(cd $(dirname $0);pwd)
echo ${CURRENT_DIR}
|
获取程序运行时间
1
2
3
4
5
6
7
8
9
|
#include <sys/time.h>
struct timeval startTime, endTime;
float timeUsed;
gettimeofday(&startTime, NULL);
...
gettimeofday(&endTime, NULL);
timeUsed = 1000000 * (endTime.tv_sec - startTime.tv_sec) + (endTime.tv_usec - startTime.tv_usec);
timeUsed /= 1000000;
printf("total times:[%f]s\n", timeUsed);
|
1
2
3
4
5
|
#include <time.h>
clock_t start = clock(); // the code need to measure time
clock_t end = clock();
double timeSpend = (double)(end - start) / CLOCKS_PER_SEC;
//得到的结果是秒,(end-start)得到的结果是毫秒,不适用于多线程场合
|
1
2
3
4
|
#include <Windows.h>
DWORD start = GetTickCount();
DWORD end = GetTickCount();
DWORD timeSpend = end - start; //得到的结果是毫秒
|
1
2
3
4
5
6
7
8
9
|
#include <Windows.h>
LARGE_INTEGER t1,t2,tc;
QueryPerformanceFrequency(&tc);
QueryPerformanceCounter(&t1);
...
QueryPerformanceCounter(&t2);
double time=(double)(t2.QuadPart-t1.QuadPart)/(double)tc.QuadPart;
printf("total times:[%lf] ms\n", time * 1000);//ms
(double)tc.QuadPart: 10 000 000
|
mpich命令
1
2
3
4
5
|
#mpiexec -l -hosts cn0,cn1 -wdir ./armcore0/host_code/ ./vec_add_host 1024 24 :\
mpiexec -l -f ./machinefile -wdir ./armcore0/host_code/ ./vec_add_host 1024 24 :\
-wdir ./armcore4/host_code/ ./vec_add_host 24 :\
-wdir ./armcore8/host_code/ ./vec_add_host 1024 24 :\
-wdir ./armcore12/host_code/ ./vec_add_host 1024 24
|
其中machinefile内容为:
表示cn0执行这4个程序一遍,如果machinefile中的内容为cn0:4则表示执行这4个程序4遍。
machinefile也可以用
代替。
免密登录
免密登录本地:
执行命令:
生成之后会在用户的根目录生成一个 “.ssh”的文件夹,文件夹下有这几个文件
-
id_rsa : 生成的私钥文件
-
id_rsa.pub : 生成的公钥文件
-
know_hosts : 已知的主机公钥清单
本地生成的公钥添加到目标服务器的 authorized_keys 文件中
1
2
|
#ssh-copy-id 将key写到远程机器的~/.ssh/authorized_keys文件中
ssh-copy-id -i .ssh/id_rsa.pub xyy@172.168.0.11
|
登录远程机器
创建新用户及用户权限
(1)在root权限下
命令:useradd +用户名,它不会在/home目录下创建同名文件夹,也没有创建密码,因此利用这个用户登录系统,是登录不了的;
命令:useradd -m +用户名,将在/home目录下创建同名文件夹,然后利用( passwd + 用户名)为指定的用户名设置密码。
useradd选项:
1
2
3
4
5
6
|
-c # comment 指定一段注释性描述。
-d # 目录 指定用户主目录,如果此目录不存在,则同时使用-m选项,可以创建主目录。
-g # 用户组 指定用户所属的用户组。
-G # 用户组,用户组 指定用户所属的附加组。
-s # Shell文件 指定用户的登录Shell。
-u # 用户号 指定用户的用户号,如果同时有-o选项,则可以重复使用其他用户的标识号。
|
(2)命令:adduser +用户名,在/home目录下会自动创建同名文件夹
创建新用户后,同时会在etc目录下的passwd文件中添加这个新用户的相关信息
创建新用户后shell无法自动补全命令或使用基本的shell命令
按照上述命令创建一个新用户后,提示符仅仅是一个$,输入命令,用TAB键也无法补全命令。并且没有命令历史功能。
使用root用户查看passwd文件
可以发现默认的shell 是/bin/sh,将其修改为/bin/bash 后即可
1
2
3
|
userdel username
#若想将它在系统上的文件也删除掉,使用命令:
userdel -r username
|
1
|
usermod --help # 查看修改用户这个命令的相关参数
|
1
|
su 用户名 # su是switch user的缩写,表示用户切换
|
1
2
|
groupadd testgroup # 组的添加
groupdel testgroup # 组的删除
|
说明:组的增加和删除信息会在etc目录的group文件中体现出来。
示例:
1
2
3
4
5
|
useradd -m xyy
passwd xyy
chown -R xyy ./xyy
chgrp -R xyy ./xyy/
vim /etc/passwd # 将其修改为/bin/bash 后即可
|
vim删除多行
linux新建用户组权限
比如找不到root下安装好的mpi
方法:修改在xyy用户下的.bashrc文件,将路径添加到末尾,再source .bashrc即可。
编译内核
1
|
make mrproper # 清空一些配置信息检查源码是否完整
|
在当前目录下执行:
1
2
3
4
5
6
|
make # 相当于make bzImage加make modules)
## 另外make可以加-j 20 意思启动20个线程编译
make modules #生成相应的模块
make modules_install #将相应的模块拷贝到对应的目录下
make install #该命令的作用是将.config,vmlinuz,initrd.img,System.map文件到/boot/目录、更新grub。默认启动新内核
|
在正式编译内核之前,我们首先必须配置需要包含哪些模块。实际上,有一些非常简单的方式来配置。使用一个命令,你能拷贝当前内核的配置文件,然后使用可靠的 menuconfig 命令来做任何必要的更改。
1
|
cp /boot/config-$(uname -r) .config
|
上述命令的意思就是拷贝对应当前内核配置到当前目录下并重命名为.config(文件名前加.意思为隐藏文件)。
可以自行查看下:
的输出
之后执行命令:
生成的配置文件在
1
|
/home/sys/linux-4.19.46-mt/.config
|
退出menuconfig后,在命令行中输入
命令即可开始编译。-j4意思是并发执行,可以提高速度,一般情况 下不要多于CPU核数。这个命令的执行会耗费很长时间。
编译完成之后首先安装模块,命令为:
1
|
sudo make modules_install
|
回到顶部
启用内核作为引导,输入下列命令将内核作为引导,将数字更改为你自己编译的版本号:
1
|
sudo update-initramfs -c -k 5.3.10
|
下面更新一下grub:
之后重启即可在启动界面选择需要启动的内核。如果看不到启动选择界面,请执行以下操作:
1
|
sudo vi /etc/default/grub
|
将文件修改为以下模式:(注释掉hidden那一行,将timeout更改为较大值,这里改为了10)之后执行
修改启动项名称:
在ubuntu下,可以直接修改/boot/grub/grub.cfg中有关启动项的名称。
复制/boot/grub/grub.cfg有关启动项的内容到/etc/grub.d/40_custom进行自定义即可。
最后都要执行下述命令以生效。
按时间列举目录下文件
DD复制硬盘
1
2
3
4
5
6
7
8
|
#查看硬盘盘符:
fdisk -l|grep /dev/sd
#格式化硬盘:
mkfs.ext4 /dev/sdn # n=要格式的盘id
#拷贝硬盘:
dd if=/dev/sdj of=/dev/sdk bs=64M
|
shell脚本获取当前路径
1
2
3
|
#!/usr/bin/env bash
Cur_Dir=$(pwd)
echo $Cur_Dir
|
1
2
3
4
5
6
|
#!/usr/bin/env bash
basedir=cd $(dirname $0); pwd -P
echo $basedir
# dirname $0,取得当前执行的脚本文件的父目录
# cd dirname $0,进入这个目录(切换当前工作目录)
# pwd,显示当前工作目录(cd执行后的)
|
查看文件夹大小
1
2
|
du -h –max-depth=1 /var/log/*
du -sh /*
|
查看文件夹下有多少个文件
- 查看文件夹下有多少个文件,多少个子目录需在终端输入
1
|
/bin/ls -l |grep ^-|wc -l
|
环境变量
1
2
|
/etc/profile.d
# 用户每次登录,会执行该文件夹下的所有.sh文件
|
网络bind error
1
2
|
# Address already in use
netstat -tanlp
|
查看内核版本
1
2
|
cat /etc/issue
cat /proc/version
|
查看cpu个数及核心数
总核数 = 物理CPU个数 X 每颗物理CPU的核数
总逻辑CPU数 = 物理CPU个数 X 每颗物理CPU的核数 X 超线程数
1
|
cat /proc/cpuinfo| grep "physical id"| sort| uniq| wc -l
|
1
|
cat /proc/cpuinfo| grep "cpu cores"| uniq
|
1
|
cat /proc/cpuinfo| grep "processor"| wc -l
|
1
|
grep 'processor' /proc/cpuinfo | sort -u | wc -l
|
注意,此处查看的线程数是总的线程数,可以理解为逻辑cpu的数量
设置堆栈大小
1
2
3
4
5
6
7
8
9
10
11
12
13
|
#include <sys/resource.h>
struct rlimit rlim, rlim_new;
if (getrlimit(RLIMIT_STACK, &rlim) == 0) {
printf("****** [%d]: %ld %ld ******\n", __LINE__, rlim.rlim_cur, rlim.rlim_max);
// rlim_new.rlim_cur = rlim_new.rlim_max = RLIM_INFINITY;
rlim_new.rlim_cur = rlim_new.rlim_max = rlim.rlim_cur;
if (setrlimit(RLIMIT_STACK, &rlim_new)!=0) {
rlim_new.rlim_cur = rlim_new.rlim_max = rlim.rlim_max;
setrlimit(RLIMIT_STACK, &rlim_new);
}
}
getrlimit(RLIMIT_STACK, &rlim);
printf("****** [%d]: %ld %ld ******\n", __LINE__, rlim.rlim_cur, rlim.rlim_max);
|
mkstemp
1
2
|
#include <stdlib.h>
int mkstemp(char * template);
|
函数说明:
mkstemp()用来建立唯一的临时文件. 参数template 所指的文件名称字符串中最后六个字符必须是XXXXXX.
mkstemp()会以可读写模式和0600 权限来打开该文件, 如果该文件不存在则会建立该文件. 打开该文件后其文件描述词会返回.
文件顺利打开后返回可读写的文件描述词. 若果文件打开失败则返回NULL, 并把错误代码存在errno 中.
错误代码:EINVAL 参数template 字符串最后六个字符非XXXXXX. EEXIST 无法建立临时文件.
查看内核版本号
lspci -k
选项表示输出信息中显示正在使用的驱动和内核中可以支持该设备的模块。
系统时间设置
1
2
3
|
date 1118184321
# 11 18 18 43 21
# 月 日 时 分 年
|
查找指定字符串
1
|
grep -rn reserve_all_mem_mt_safe
|
开机自动加载模块
将需要加载的.ko文件放到
1
|
/lib/modules/$(uname -r)/update
|
新建的文件夹下
然后执行depmod即可,在
1
|
/lib/modules/$(uname -r)/modules.dep
|
文件中能看到需要加载的.ko文件
或在
文件中添加
编译成模块
1
|
make -C /home/sys/linux-4.19.46-mt/ M=`pwd` modules
|
卸载PCI设备
1
|
echo 1 > /sys/bus/pci/device/0000\:03\:00.0/remove
|
重新对PCI/PCIe总线进行枚举,可执行命令
1
2
3
4
5
|
echo 1 > /sys/bus/pci/rescan
$make modules
$sudo make modules_install
$sudo make install
update-initramfs: Generating /boot/initrd.img-4.19.46-vfio-1119+
|
vscode添加头部注释
1
2
|
ctrl + alt + i # 生成头部注释
ctrl + alt + t # 生成函数注释
|
Linux C内存泄漏检查
1
|
valgrind --tool=memcheck --leak-check=full ./test
|
Linux程序前台后台切换
- 在Linux终端运行命令的时候,在命令末尾加上 & 符号,就可以让程序在后台运行
1
|
root@Ubuntu$ ./tcpserv01 &
|
- 如果程序正在前台运行,可以使用 Ctrl+z 选项把程序暂停,然后用 bg %[number] 命令把这个程序放到后台运行,摁Ctrl+z,然后在最后一行加上
- 对于所有运行的程序,我们可以用jobs –l 指令查看
1
|
[kettle@4 data-integration]$ jobs -l
|
- 也可以用 fg %[number] 指令把一个程序掉到前台
1
2
|
cat@Ubuntu:~/unp/unpv13e/tcpcliserv$ fg %1
./tcpserv01
|
- 也可以直接终止后台运行的程序,使用 kill 命令
1
|
cat@Ubuntu:~/unp/unpv13e/tcpcliserv$ kill %1
|
任意类型循环左右移位n位
1
2
3
|
#define LOGIC_LSHIFT_NBIT_TYPE(data, nbit, type) ((type)((data >> (sizeof(type) << 3) - nbit) | (data << nbit)))
#define LOGIC_RSHIFT_NBIT_TYPE(data, nbit, type) ((type)((data << (sizeof(type) << 3) - nbit) | (data >> nbit)))
#define LOGIC_RSHIFT_NVLAN(data, nbit) ((data | (1 << (nbit))) | 0xFFFFFFF)
|
lspci -vv
Linux 中用于显示 PCI/PCIe 设备超详细硬件信息的命令
__builtin_popcount
GCC 编译器中四个重要的内置函数之一。__builtin_popcount(x):该函数用于计算一个整数的个数(设置位)。
绑定CPU的C代码实现
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
|
#define _GNU_SOURCE
#include <sched.h>
void set_CPU_affinity(int core_id)
{
cpu_set_t mask;
CPU_ZERO(&mask);
CPU_SET(core_id, &mask);
sched_setaffinity(0, sizeof(cpu_set_t), &mask);
}
void get_CPU_affinity()
{
cpu_set_t get;
CPU_ZERO(&get);
if (sched_getaffinity(0, sizeof(get), &get) == -1)//获取线程CPU亲和力
{
printf("warning: cound not get thread affinity, continuing...\n");
}
int i;
for (i = 0; i < 16; i++)
{
if (CPU_ISSET(i, &get))//判断线程与哪个CPU有亲和力
{
printf("this thread %d is running processor : %d\n", i,i);
}
}
}
|
cgroup执行命令
使用 Linux cgroups(控制组)来限制进程 CPU 资源
1
|
cgexec -g cpu:test_cpu ./a.out
|
/bin/bash有字符’\r’无法解析
1
2
3
|
vi hello.sh
### Esc进入命令行运行模式
### : set ff=unix
|