Linux知识(一)

实际中碰到的一些问题或一些知识的记录,发到博客备忘,也供大家参考。每个条目之前顶头有个“-”。


- top监控线程信息,使用H子命令或参数, -p PID可以指定监控哪个进程的线程

- 设置gdb提示符的颜色:set prompt \033[0;33mgdb>>>\033[0m\040
得到的提示符是浅黄色的"gdb>>>",可以修改成自己所需,比如需要浅黄色"(gdb)",则
set prompt \033[0;33m(gdb)\033[0m\040
可以写入到HOME目录的.gdbinit文件中,注意末尾\040代表一个空格。

- 创建静态库
ar -r <archive-file> <object-files>
gcc检索目标文件和库文件的顺序是从左到右(UNIX过去的编译器的行为特征),t01.o lt02 t03.o,则gcc先检查t01.o,然后是t02库,然后是t03.o,所以如果t01调用t02库中的函数,那么t02库要放在t01.o的后面,这样当t01.o检查到一个外部引用时,编译器接下来可以在t02库中找到;如果t02库放在前面,t01.o放在后面,那么编译器在检查t01.o遇到一个外部引用时不会再到前面去搜索t02库,而在t03.o中(我们假定)又找不到,那么就会报“Undefined reference”的错。
注意:gcc只是对库文件的顺序要求严格,如果都是.o文件,那么顺序不会导致问题。
gcc的行为可以看作是从左到右一趟扫锚的模式。
网上给出一个优化顺序模板:g++ ...  obj($?) -l(上层逻辑lib) -l(中间封装lib) -l(基础lib) -l(系统lib)  -o $@


- linux下将数字补齐为固定宽度的方式
可以使用awk命令处理
如:
echo 1245| awk '{printf("%06d\n",$0)}'
或用printf命令,printf %06d\\n $var
注意可能会遇到禁止问题,报错:“value too great for base (error token is "08"”,这需要做一个进制转换,8进制转成10进制,如下所示:
tsecond=$(date +%S) 做一个强制转换--> tsecond=10#$(date +%S),强制转换方法似乎是在算术表达式中进行的。$((10#var))
Bash字符串数字默认是八进制。

- 字符串数字自动加1保持等宽。
NUM=`printf "%06d\n" $((10#$NUM+1))`;echo $NUM
第一个命令起作用,第二个仅是查看而已。
原理是将变量NUM转换成十进制然后加1,再通过printf命令赋值回去。

- Bash中的{}复合命令(compound command)
{ list; }
其中“{”和“}”必须用空格隔开,“;”也是必不可少的。list的形式可以是command1;command2;...

- sudo执行复杂的命令,比如包含重定向或者管道之类的命令,下面是几种方法
- echo "<command>" | sudo sh
- sudo sh -c "<command>"

- 远程登录执行sudo命令会出现“sudo: sorry, you must have a tty to run sudo”的错误,解决方法:
- ssh使用-t参数
    ssh -t user@box.example.com sudo command1 /path/to/file
- 修改The requiretty option in sudoers file
- 使用su命令
    ssh user@server1.nixcraft.in su --session-command="/path/to/command1 arg1 arg2"
    
- export PS1=${PS1}'\n>' 命令将bash提示换行,并在下一行用‘> ’提示。    

- grep匹配英文句号(<str>代表一个常规即不含特殊字符的字符串)
grep <str>\. file         #匹配<str>加上任意一个字符
grep '<str>.' file         #匹配<str>加上任意一个字符
grep '<str>\.' file        #匹配<str>加上'.'(即英文句号)
grep "<str>\." file     #匹配<str>加上'.'(即英文句号)
原因是什么?这时因为我们输入的命令行这一串字符串首先要经过shell的解析,然后像grep这种命令,“<str>\.”是作为模式输入的,所以grep命令本身还要将传递给它的模式的解析,然后才能得出真正要匹配的字符。
“<str>\.”和“'<str>.'”经过bash解析后,传递给grep的都是“<str>.”,后面那个“.”,正好被grep解析为代表任意字符。
“'<str>\.'”和“"<str>\."”经过bash解析后,传递给grep的都是“<str>\.”,所以grep解析这个模式时,因为转义符\的存在,“.”会被认为代表该字符本身。

- 以可执行文件执行的脚本,其中包含exit命令时不会导致当前shell退出,但是用source方式执行会导致退出。


- bash对于字符串的内部表示
所谓内部表示,我这里是指打开-x开关后看到的字符串表示。在脚本中输入下面两行,存为test.sh:
AASTR="a''a"
echo ${AASTR}
上面脚本的意思是,在屏幕上打印字符串:a''a。执行bash -x test.sh,显示结果是
+ AASTR= 'b a'\'''\''a c'
+ echo  b 'a'\'''\''a' c
b a''a c
也就是说,第一个变量赋值的内部表示,是'b a'\'''\''a c',
第二个Echo命令的内部表示,是b 'a'\'''\''a' c。可以发现这里“'”的使用方式与bash中Quote部分的规定差别很大。似乎是除了最外层的“'”算是一种表示括起来的分隔符的之外,剩下的“'”都是以栈的方式进行匹配和分析的。比如“'b a'\'''\''a c'”去掉最外层之后,'\''可以解析为' \' ',其中\'表示'字符本身,而它前后两个“'”表示一对匹配的其分隔符作用的“'”。

- 用bash -x打开一个新的shell环境能看到很多内部细节。

- 非交互式指定用户名和密码ssh登录azure的linux虚拟机,修改root密码,并删除登录账户
azure创建Linux虚拟机的时候,需要指定一个账户和密码(不能是root),然后以这个账号
和密码ssh登录虚拟机。如果必须以root登录,那么应该怎么办?只能先sudo修改root密码,
然后再以root身份登录。如果不采用交互式输入密码的方式,而是要在脚本里用一条命令完成,
那有应该如何呢?
这里面遇到几个问题需要逐一解决。1. ssh命令不能指定密码,非得输入,如何解决?
2. 首次sudo也需要输入密码,如何解决?
3. passwd命令也需要输入密码,如何解决?
4. 第一个ssh会询问是否保存密钥,需要输入yes/no,如何解决?
5. 执行sudo命令,会提示需要一个终端设备,如何解决?
第一个问题可以用putty系列(源码编译)中的plink程序解决,plink可以用过-l选项和-pw选项
分别指定登录用户名和密码。
第二个问题采用的方式是是指定sudo的-S选项然后用echo "password" | sudo -S <command>的形式。
第三个问题指定passwd的--stdin方式,然后也用echo "password" | passwd --stdin <username>的形式。
第四个问题:ssh可以采取在~/.ssh/config文件中写入下面的配置(openssh):
Host 192.168.1.1(主机ip)
StrictHostKeyChecking no
UserKnownHostsFile=/dev/null
或者使用ssh-keyscan命令针对主机生成host key,然后加入~/.ssh/known_hosts文件中

plink可以采用echo y | plink ...的形式。
或者先使用ssh-keyscan针对主机生成konwn_hosts格式,然后再使用putty自带的py脚本kh2reg.py(在contrib目录下)转换成putty的sshhostkey格式,命令
echo <host-ip/name> | ssh-keyscan -t rsa -f - | kh2reg.py --unix
第5个问题:ssh和putty都可以用-t选项

因为指定密码只能使用plink,所以最终的结果是使用下面命令(USER,PASS,VIRTUALIP分别是用户名,密码和主机ip)。
echo y | ./plink -l ${USER} -pw ${PASS}  ${VIRTUALIP} echo -e \nSuccessfully Logined!\n #用个简单命令生成sshhostkey文件,下次就不会再次验证了。不要使用-batch参数,否则会不给提示。
./plink -l ${USER} -pw ${PASS} -t ${VIRTUALIP} "echo ${PASS} | sudo -S -p '' sh -c 'echo ${ROOTPASS} | passwd --stdin root'"
附:下面两个命令行在命令行环境下是等价的,但在脚本中如果ROOTPASS要展开的话,可能会有区别。
./plink -l testuser -pw @Wip2014 -batch -t 42.159.229.210 'echo @Wip2014 | sudo -S -p "" sh -c "echo 12345678 | passwd --stdin root"'[OK]
./plink -l testuser -pw @Wip2014 -batch -t 42.159.229.210 "echo @Wip2014 | sudo -S -p '' sh -c 'echo Hds654321 | passwd --stdin root'"[OK]


- ps列出所有进程并安装命令名字排序(所谓命令名即通常ps(不带参)显示的最后一列)
ps -e --sort cmd

- 查看LINUX进程内存占用情况
  可以直接使用top命令后,查看%MEM的内容。可以选择按进程查看或者按用户查看,如想查看oracle用户的进程内存使用情况的话可以使用如下的命令:
 (1)top
  top命令是Linux下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况,类似于Windows的任务管理器
  可以直接使用top命令后,查看%MEM的内容。可以选择按进程查看或者按用户查看,如想查看oracle用户的进程内存使用情况的话可以使用如下的命令:
  $ top -u oracle
内容解释:
  PID:进程的ID
  USER:进程所有者
  PR:进程的优先级别,越小越优先被执行
  NInice:值
  VIRT:进程占用的虚拟内存
  RES:进程占用的物理内存
  SHR:进程使用的共享内存
  S:进程的状态。S表示休眠,R表示正在运行,Z表示僵死状态,N表示该进程优先值为负数
  %CPU:进程占用CPU的使用率
  %MEM:进程使用的物理内存和总内存的百分比
  TIME+:该进程启动后占用的总的CPU时间,即占用CPU使用时间的累加值。
  COMMAND:进程启动命令名称
  常用的命令:
  P:按%CPU使用率排行
  T:按MITE+排行
  M:按%MEM排行

(2)pmap
  可以根据进程查看进程相关信息占用的内存情况,(进程号可以通过ps查看)如下所示:
  $ pmap -d 14596

(3)ps
  如下例所示:
  $ ps -e -o 'pid,comm,args,pcpu,rsz,vsz,stime,user,uid'  其中rsz是是实际内存
  $ ps -e -o 'pid,comm,args,pcpu,rsz,vsz,stime,user,uid' | grep oracle |  sort -nrk5
  其中rsz为实际内存,上例实现按内存排序,由大到小

- 关于systemd的几个知识
systemd是启动进程管理器,在Fedora 15时集成到fedora中;RHEL 7基于Fedora 19,所以使用systemd;
systemd的两个重要目录/etc/systemd/system,这个目录它的目录层次结构的根目录;
/lib/systemd/system中存放了所有服务单元文件。

指定systemd在系统启动时启动某个服务实际上是建立该服务单元文件(在/lib/systemd/system中)
到目标单元(target)目录中建立一个链接(/etc/systemd/system)。
取消启动时实际上是删除一个链接。
链接还控制默认运行级别(默认target)

systemctl isolate 命令改变当前运行级别(目标)。回到图形运行级别,如下:
# systemctl isolate graphical.target

- YUM更新软件
列出所有可更新的软件清单
命令:yum check-update
安装所有更新软件
命令:yum update
仅安装指定的软件
命令:yum install <package_name>
仅更新指定的软件
命令:yum update <package_name>
列出所有可安裝的软件清单
命令:yum list

- grep -v -e ^# -e ^$ <file-name>
显示文件中非空行,非#开头的行

- /etc/fstab和/etc/mtab的区别
fstab是开机时将要挂载的,而mtab是系统当前已经挂载的。

- 查看磁盘设备(不论挂载与否)
根用户下fdisk -l或者lsblk

- linux下使用原始磁盘
1. 查看fdisk -l或lsblk
2. 分区fdisk <device>(n 新建分区,w写入分区表信息并退出)
3. 创建文件系统mkfs.ext4(或其他命令):mkfs.exts <partition>
4. 挂载分区:mount <partition> <mount_point>

- CentOS7中,ifconfig命令在net-tools包中

- CentOS的源中,repo-id才是排序依据(即repo文件中用方括号括起来的部分)。但是软件有新版本可能会优先updates库。
而且repo-id最好不要重名。

- CentOS安装时,一定要将网卡配置成自动,否则就要到/etc/sysconfig/network-scripts/目录,执行ifup <cfg-file>命令来手动启动

- 查看网络接口设备信息的命令:
lspci | grep Ethernet
ethtool <device>
ifconfig <device>

- 跟设备管理,包括修改网络设备名称,查看udev和udevadm之类的资料
修改网络设备名字,似乎也可以通过在/etc/sysconfig/network-scripts/目录中的配置文件中指定DEVICE=<NAME>来实现。
此时执行ifup <配置文件>可能会报找不到设备的错误,重启就好。
配置文件的名字(ifcfg-*在连字符后面的部分)也要修改,至于NAME属性,不知道需不需要修改。
关机再重启?

- vmware虚拟机中安装CentOS linux的话,可以安装open-vm-tools来代替vmware-tools。
带GUI的安装,会自动安装open-vm-tools。
    
- yum临时启用或禁用某个库,使用参数--enablerepo=repoidglob, --disablerepo=repoidglob    
需要这个参数可能是因为某个被依赖包先从某个库安装了,而后面安装其他包从其他库安装。
修改了库顺序可能会导致这个问题。

- 父进程的STDOUT被关闭后,子进程的就能正常输出,程序也能正常退出。父进程的close(1)应该在它exit()之前。

- SecureCRT 5需要选择VT100终端才能将IP留在Tab上,如果选择xterm,会是<user>@<hostname>形式。
选用VT100键盘是HOME无法支持,可以选用xterm键盘(终端仍然可以选用VT100);
Activator的开关:在全局选项-->一般(是否最小化会话到activator)。但是缺省会话选项中也要修改,在“终端”中,否则也会启动activator。
在缺省选项中的开关决定最小化时,该会话是否最小化activator。

- lspci属于pciutils工具包

- grep命令_正规表示法
    ^word 行首匹配
    word$ 行尾匹配
    * 任意n个字符,可以一个都没有
    . 任意一个字符,必须有一个
    \  转义特殊字符串
    常用参数
        -i 忽略大小写
        -v 不包含指定的字符串;
        -e "正则表达式"  执行正则表达式;
        -Cnum 显示包含指定字符串的前面num行,后面num行;
        -Anum 显示包含指定字符串的前面num行;
        -Bnum 显示包含指定字符串的后面num行;
        -n 显示行号;
        -r 递归查找z;
        -c 统计出现的次数

- 查看virsh版本信息
执行virsh,进入virsh控制台;
执行version显示相关库信息
执行quit,退出virsh控制台

- 修改提示符颜色,可以通过设置PROMPT_COMMAND命令来修改,在.bashrc中设置:
PROMPT_COMMAND='export PS1="\[\e[0;33m\]${PS1}\[\e[0m\]"'  #变成黄色(不能这样,会使PS1变得极长,每次都递归修改了)
应该直接设置PS1。比如
ORIGPS1=$PS1 # 保存最初的PS1值,该命令只能执行一次。
注意:PS1中包含\$两个字符,这在命令行直接输入时,因为\$在bash展开时能够转义,成为单个字符$,所以要输入成\\$。这样在字符串中才是\$。
PS1="\[\e[0;31m]\]${ORIGPS1}\[\e[0m\]"
RHEL的系统PS1的修改在/etc/bashrc中
    在~/.bashrc加入一行来修改(设置成蓝绿色为例):
设置前景:export PS1="\[\e[0;36m\]${PS1}\[\e[0m\]"
设置背景:export PS1="\[\e[46m\]${PS1/% }\[\e[0m\] " #背景色不包括最后一个空格(${PS1/% }的作用)
颜色值范围,前景:30~37,背景:40~47。\e[0m表示恢复默认。“\[ \]”表示输入转义序列


- nohup命令和后台执行(末尾加&)的区别是nohup忽略HUP信号,而HUP信号是终端退出时发给依赖于它的进程的信号,后台执行还是依赖于终端的;所以command &在终端退出时command也会终止,而nohup command &在终端退出时,command依然运行。

- Linux非常国际化,里面经常出现语言、国家代码。在国家代码中,ISO 3166对于英国的编码是GB(Great Britain),而另外一个标准中,美国的FIPS 10-4,英国的编码是UK(此时GB代表Gabon);但是2008年,美国NIST撤销了FIPS 10-4,代之以基于ISO 3166指定的标准。
FIPS代码可能还用于很多Linux发行版,需要注意。

- route命令add或del路由的时候target gw 和 netmask都是要指定的,还有interface也要指定好。
route del时似乎target gw和netmask都不可少。

- 关于/etc/sysconfig/目录的一些文件的说明,一般在/usr/share/doc/initscripts-*/sysconfig.txt文件中可以找到。

- 计算文件行数,只输出结果数字(wc如果以文件名作为输入,还会输出文件名):
cat <filename> | wc -l
或者 grep -c -e '^' <filename>

- cut命令输出每行的一个部分(截取部分输出)
-d "<char>",以什么为分界符
-f <num>  选择哪些部分,以逗号分隔

- tr 删除字符串中的多余部分,或者转换
删除:-d <string-of-chars-to-be-deleted>
保留:-c -d,-c是反转删除的意思
tr的本义实际上是转换

- vim中删除空行或者空白行
在vim中执行:“:g/^\s*$/d”

- 查看本机所有ip,或第一个IP
hostname -I (所有IP)
hostname -i (第一个IP)(有时上面命令可以执行,返回结果,但是下面一个没有结果)

- 直接查看manpage文件,man -l <filename>,filename是如*.1之类名字形式的文件

- 直接在.bash_profile里面设置TERM变量为xterm或者xterm-color,可以像xterm一样显示颜色,而不管使用登录软件时是以什么终端模拟的(比如secureCRT使用VT100登录时没有颜色,设置TERM变量之后就有了)

- 好好的系统突然出现一个“Ubuntu is running in low-graphics mode”的错误,解决方法是安装ctrl+alt+f1或启动时选择一个login console,然后执行:
sudo dpkg-reconfigure -phigh xserver-xorg

- Ubuntu 14.04的Sunpinyin的双拼键映射不对,需要下载一个包安装再重启解决:
http://ftp.hk.debian.org/debian/pool/main/o/open-gram/sunpinyin-data_0.1.22+20131212-1_amd64.deb

- Ubuntu 14.04返回经典界面:
sudo apt-get install gnome-session-fallback
然后在登录时session风格选择fallback即可,或者metacity也可以

- 续行符"\"一定要是最后一个字符,如果后面有空格,续行符就会失去续行的效果。
续行符一般就是转义引导符

- cpu信息查看
可以通过/proc/cpuinfo文件直接查看,更好的是通过lscpu命令查看(这个命令是利用了概文件的数据),不过更为直观。

- cp -P 可以拷贝链接文件本身,而不会检查链接目标是否存在。如果不使用-P,则会检查,并可能报文件不存在(实际上是链接文件移动之后,其链接就不正确了)

- 查看linux何时启动,重启,登录信息:分别命令是who -b, last reboot, last -x。

- grep要在某个文件查找“[ml2]”,怎么办?命令是:grep \\[ml2\\] filename
道理是:bash命令行有一个转义,grep本身对字符有一个转义。命令行上\\[ml2\\]传给grep的是\[ml2\],
而命令行上\[ml2\]经过转义之后传给grep的还是[ml2]。

- 生成一个空文件,不管原来是不是已经有了这个文件:
 echo -n > <file-name>

- awk的返回一行文本的话,要注意是需要多个词的组合还是单个词,如果是单个词应该在上面加上双引号。

- parted将整个磁盘做成一个分区:parted  /dev/sdX mklabel msdos unit '%' mkpart primary ext4 0 100

- bash的条件测试:对于空串或未定义变量的操作
  看一个字符串是否为空,可以通过 -n 或 -z来判断。按照操作符的意义,变量VAR而言,如果VAR为空或未定义,
  那么-n测试结果应该为假,而-z应该为真。反之,如果不空,则-n为真,-z为假。
  采用条件测试的列表形式,即“[ -n $VAR ] && echo TRUE”,如果输出TRUE,则表明条件测试结果为真。
  经过测试,显然VAR不空时,测试结果都正常,而VAR为空,测试结果都是真,原因何在?
  将上面语句写入脚本,并用bash -x 执行,发现测试条件成为了“'[' -n ']'”,也就是说经过分词之后,
  为空的变量实际上消失了,测试命令变成了只有“-n”这么一个参数,而查看bash手册(bash4.2)中关于test(与'['命令等价,
  注意“[”实际上是一个命令)命令求值的解释,发现只有一个参数而且参数不空的时候,求值都为真。也就是说,将
  “-n”换成别的什么测试操作符,比如“-z”或“-e”,测试结果都是真。一试,果不其然。
  解决办法是什么呢?
  方法一,不直接使用变量${VAR},而是后面附加一个任意字符,然后比较与此字符是否相等来测试,变量是否为空。
  比如“[ ${VAR}y == y ] && echo TRUE”,会输出TRUE,而“[ ${VAR}y != y ] && echo TRUE”就不会输出。
  方法二,使用“if [[ conditional-expression ]] ”的形式。其中“[[”是关键字而不是命令。这种形式下“[[ ... ]]”不会
  进行分词处理,所以用bash -x执行脚本,发现“[[ -n $VAR ]]”成了“[[ -n '' ]]”,就是说空串依然作为一个参数
  保存下来了,根据test的求值规则,这是两个参数了,所以测试操作符就能正常工作了。

- awk '/ pattern / {print $1 $2}' 与 awk '/ pattern / {print $1, $2}'的区别
  前者输出的$1和$2之间无空格,后者有空格。一般来讲,逗号表示分隔,缺省分隔符为空格。可以用过OFS变量设置为其他分隔符;
  比如awk '/ pattern / {print $1, $2}' OFS="\t",以Tab键分隔。
 
- 两个ifstat
CentOS7的iproute-3.10.0的软件包中自带了一个ifstat命令,功能比较简单;
另外一个功能强大也是通常所用的ifstat命令是Gaël Roualland编写的软件。网址是http://gael.roualland.free.fr/ifstat/。它依赖net-snmp包(http://net-snmp.sourceforge.net/)。
如果要使用yum来安装的话,可以从Fedora 21的软件包中下载ifstat-1.1-19.fc21.x86_64.rpm和
net-snmp-libs-5.7.2-23.fc21.x86_64.rpm(前者依赖后者),然后安装。

在CentOS7中,iproute包中ifstat命令是在/usr/sbin/下,而ifstat包安装后ifstat命令是在/usr/bin目录下,要用后者则将前者重命名(因为在CentOS7的PATH变量中,/usr/sbin/在/usr/bin之前)。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值