nc命令可用于发送任务tcp/udp连接和监听.
官方描述的主要功能包括:
下面看看官方的几个例子:
在A机器运行(假设A机器主机名为node1
:
nc -l 1234 # -l表示监听
在B机器运行:
nc node1 1234
此时从A或者B机器输入任何信息,都会在对方的机器中回显,实现了简单的即时聊天工具.
假设B机器有一个文件data.txt,需要传输到A机器:
在A机器:
nc -l 1234 >data.txt # data.txt需要保存的目标文件名
在B机器:
nc node1 1234 <data.txt # data.txt需要传输的文件
假设B需要远程操作A,又没有安装ssh:
在A机器:
rm -f /tmp/f; mkfifo /tmp/f
cat /tmp/f | /bin/sh -i 2>&1 | nc -l 127.0.0.1 1234 > /tmp/f
在B机器:
nc node1 1234
echo "GET / HTTP/1.0\r\n\r\n" | nc localhost 80
# 查看主机名为node1的80端口是否开放
nc -zv node1 80
# 扫描主机名为node1的1~1024哪些端口是开放的
nc -zc node1 1-1024
sed -e ':a;N;s/\n//;s/ //g;ba' test.txt
or
cat test.txt | tr -d '\n '
xargs -0
或者 --null
表示分隔符为0
字符, -n
表示每次传参数的最大个数
cat /proc/$$/environ | xargs -0 -n 1
cat /proc/$$/environ | tr '\0' '\n'
export LD_LIBRARY_PATH=/opt/myapp/lib
支持 ++
--
+
-
*
/
**
&
|
等
a=$((5 ** 5)) # a = 3125, 等价a = let 5 ** 5
echo "scale=3; 10 / 3" | bc # 浮点数
[[ 'a5a' =~ [a-zA-Z][0-9][a-z] ]] && echo "YES" || echo "NO"
# 注意 =~ 后面的正则表达式不能用引号
>&
实际复制了文件描述符, ls >dirlist 2>&1
与 ls 2>&1 >dirlist
不一样
declare -a a
把变量a声明为索引数组declare -A a
把变量a声明为关联数组${a[@]}
获取所有的值, ${!a[@]}
获取所有的键 ### 7. exec & source\(command1;command2\)\
: 将命令置于新进程,继承父进程所有文件描述符
declare -A map
map[key]=value
map=([key1]=value1 [key2]=value2)
keyset: ${!map[@]}
values: ${map[@]}
map[count]=0
let map[count]++
out="$(ls)"
IFS
IFS=','
line='1,2,3,4,5'
for i in line
do
echo $i
done
# 迭代
for i in list
do
echo $i
done
# range
for i in {1..50}
do
echo $i
done
# c 风格
for((i = 0; i <= 50; ++i))
do
echo $i
done
cat - a >out # 从标准输入流输入内容插入a中
cat -s 过滤多余空行
#删除所有的swp文件
find . -maxdepth 1 -type f -name "*.swp" -delete
# 将10天前的文件复制到OLD目录
find . -maxdepth 1 -type -f -mtime +10 -name ".txt" -exec cp {} OLD \;
echo -n "split:split:split:split" | xargs -d : -n 2
split split
split split
#output
split split
split split
# 统计c代码行数
find . -maxdepth 1 -type f -name ".c" -print0 | xargs -0 wc -l
# 注意print0 和-0 表示以null作为分隔符,防止文件名包括空格回车造成错误
# 小写转化大写
echo "heLLo" | tr 'a-z' 'A-Z'
echo "heLLo" | tr '[:lower:]' ''[:upper:]'
# 空格转化为回车
echo "1 2 3 4" | tr ' ' '\n'
# 删除数字
echo "abcd123dd" | tr -d '0-9' # abcddd
# 保留数字
echo "abcd123dd" | tr -d -c '0-9' # 123
# 压缩字符
echo "aaabbbccc" | tr -s 'ab' # abccc
# 求和
echo '1 2 3 4 5' | echo $[ $(tr ' ' '+') ]
# 产生校验
md5sum test.txt >test.md5
# 校验
md5sum -c test.md5
# 默认按字典序排列
echo "3 2 1 13 11 12" |tr ' ' '\n' | sort | tr '\n' ' ' # 1 11 12 13 2 3
# 使用-n按大小排序
echo "3 2 1 13 11 12" |tr ' ' '\n' | sort -n | tr '\n' ' ' # 1 2 3 11 12 13
# 使用-r表示逆序
# 检查文件是否排序
sort -C test1 && echo "sorted" || echo "unsorted"
# 使用-k指定哪个列作为键
# -b 忽略前导空白行
# -m 把已排好序的文件归并
# 注意该文件必须保证是已排好序的文件
# 过滤重复行
echo "1 2 2 3 3 3" | tr ' ' '\n' | uniq # 1 2 3
# 只输出唯一行
echo "1 2 2 3 3 3" | tr ' ' '\n' | uniq -u # 1
# 统计重复次数
echo "a b b c c c c" | tr ' ' '\n' | uniq -c # 1 a 2 b 4 c
# 输出重复行
echo "a b b c c c c" | tr ' ' '\n' | uniq -d # b c
# 获取文件扩展名
${file#*.}
# 或者文件名
${file%.*}
# 把*.JPG 重命名为*.jpg
rename *.JPG *.jpg
# 将文件名的空格替换为_
rename 's/ /_/g' *
# 转化文件大小写
rename 'y/a-z/A-Z/' *
a=() # 声明一个空数组
a+=(1 2) # 追加1 2 到数组a中
PIDS=()
for i in {1..50}
do
echo $i >>out &
PIDS+=("$!") # $!表示最后一个后台进程pid,追加到PIDS数组中
done
wait ${PIDS[@]}
# 两个文件必须是排好序的
comm A.txt b.txt
# 第1列包含只在A文件(A的差集),2列包含只在B文件(B 的差集),
# 第3列包含A、B相同的行(A、B的交集)
# -1 -2 -3 分布表示删除第1,2,3列
# 查看文件差异
diff a.txt b.txt
# 打补丁
diff a.txt b.txt >patch
patch a.txt < patch
# 取消补丁
patch -p1 a.txt <patch
# 生成目录
diff -Naur d1 d2
# -r 递归 -N:缺失文件视为空文件 -u:生成一体化输出 -a 将所有文件视为文本文件
head -n num
# num 为正数,则只输出前num行,默认为10,若num为负数,则输出前num行以外的行
tail -n num
tail -f file
#当进程PID停止,tail自动退出
tail -f --pid $PID file
ls -d */ # 不能少/
ls -F | grep "/$"
ls -l | grep "^d"
find . -maxdepth 1 -type d -print
# -o 只输出匹配的文本部分
# -c 统计匹配行数(不是次数)
# 求匹配次数
grep -o '[0-9]+' | wc -l
# 打印行号 -n
# -b打印偏移量,常常和-o连用
# -l 只打印匹配的文件列表,-L打印不匹配的文件列表
# -R 递归
# -i 忽略大小写
# 匹配多个样式, -e
grep -e 'pattern1' -e 'pattern2'
# 指定文件
# 只搜索c或者cpp文件
grep --include *.{c,cpp}
# --exclude "README.md" 不搜索该文件
# -Z 输出以0作为文件名终结符,与-l结合使用
grep -Zlr "test" *
# -q 不输出任何东西,匹配返回0,不匹配返回1
# -A -B -C 输出上下文-A向后输出n行,-B向前输出n行,-C 向前向后输出n行
# -f 指定列, 与--complement结合,输出不包括这些列的所有列 -f 3,5打印第3,5列
# -f 3- 打印从第3列开始的所有列
# -c字符 -b字节 -f字段
# -v 传递外部变量
# getline读取一行,尤其在BEGIN块使用过滤头部信息
# getline var,var保存内容,若调用不带参数的getline,则可以使用$0-$9访问
# -F列分隔符
bash支持两种数组,一种是索引数组,一种是关联数组
数组的值类型是任意的,索引也未必一定要连续,当做列表理解更好
下面总结下索引数组,即列表:
declare -a a
a=(1 2 3 4)
# OR
a=([0]=2 [3]=8) # 注意长度为2,不是4
size=${a[@]}
a+=(11 12 13 14)
a[1]=9
value=${a[0]} # 读取索引0的值
unset a[0]
unset a
echo ${a[@]:1:3} # 从索引1开始的3个元素
# 也支持负数索引,-1表示最后一个,但负数必须用括号括住
last=${a[@]:(-1):1}
for i in ${a[@]}
do
echo $i
done
declare -A map
map[key1]=value1
map[key2]=value2
# or
map=([key1]=value1 [key2]=value2)
size=${!map[@]}
keyset=${!map[@]}
values=${map[@]}
for key in ${!map[$@]}
do
echo $key:${map[$key]}
done
从bash 4开始支持关联数组,使用前需要声明,即
declare -A map
map[key1]=value1
map[key2]=value2
map=([key1]=value1 [key2]=value2)
# 获取keys
keys=${!map[@]}
# 获取values
values=${map[@]}
利用关联数组,很容易实现单词统计,源码文件wordCount.sh
#!/bin/bash
if [[ $# -lt 1 ]]
then
echo "Usage: $0 <filename>"
exit 1
fi
file=$1
declare -A count
for word in $(grep -P -o '\b\w+\b' $file)
do
let count[$word]++
done
for word in ${!count[@]}
do
printf "%-14s%s\n" $word ${count[$word]}
done
使用方法
./wordCount.sh filename
或者从标准流中使用,如
echo "Hello World! GoodBye World!" | ./wordCount.sh -
输出为
Hello 1
World 2
GoodBye 1
windows pupppet只能安装agent,安装过程,在这里. 安装过程比较简单,但在运行agent时会遇到几个问题。
这是win32-dir库bug,需要升级,使用管理员身份运行start command prompt with puppet,然后运行:
gem install win32-dir
gem list
确保运行gem list后win32-dir版本大于0.4.3。
这是由于编码问题造成的,master在获取facter变量时不能有中文(或者保证传输的编码和master一致),运行facter后发现timezone 输出中文。简单的解决办法是,修改facter的timezone,位于
安装路径:C:\Program Files\Puppet Labs\Puppet\facter\lib\facter.
根据实际情况修改setcode值,我是直接硬编码为"UTC+8",或者可以参照世界时区标准记法。
这是由于agent和master clock不同步造成的,openstack中创建windows云主机时需要指os_type为windows,才能社会之RTC为localtime,否则使用UTC时间,差了8个小时,与master时间对不上。
bash内置变量IFS作为内部单词分隔符,其默认值为<space><tab><newline>, 我想设置它仅为\n,于是:
OLD_IFS=$IFS
IFS='\n'
# do some work here
IFS=$OLD_IFS
但结果为:IFS把单独的字符当作了分隔符,即分隔符被设置成下划线和字母n 。
Why ?
通过google搜索,得知需要把\n转化成ANSI-C Quoting, 方法是把字符串放入$'string'中,即应该设置成:
IFS=$'\n'
顺便搜了下$字符的用途,在Unix & Linux, 中解释了字符串前面加$字符的两种形式,一种是单引号,一种是双引号,即
There are two different things going on here, both documented in the bash manual
$'
Dollar-sign single quote is a special form of quoting: ANSI C Quoting Words of the form $'string' are treated specially. The word expands to string, with backslash-escaped characters replaced as specified by the ANSI C standard.
$"
Dollar-sign double-quote is for localization: Locale translation A double-quoted string preceded by a dollar sign (‘$’) will cause the string to be translated according to the current locale. If the current locale is C or POSIX, the dollar sign is ignored. If the string is translated and replaced, the replacement is double-quoted.
因此单引号表示转化成ANSI-C字符,双引号则表示将字符串本地化。
以下是一个实例,ping /etc/hosts的主机名为video-开头的主机名,检查网络状况!
#!/bin/bash
trap "echo 'interrupted!';exit 1" SIGHUP SIGINT SIGTERM
OLD_IFS=$IFS
IFS=$'\n'
for i in `awk '$0!~/^$/ && $0!~/^#/ && $2~/^video/ {print $1,$2}' /etc/hosts`
do
ADDR=$(echo $i | cut -d' ' -f 1)
DOMAIN=$(echo $i | cut -d' ' -f 2)
if ping -c 2 $ADDR &>/dev/null
then
echo $DOMAIN ok!
else
echo $DOMIN dead!
fi
done
IFS=$OLD_IFS
使用lspci命名查看显卡系列
lspci -vnn | grep -i VGA 12
输出
01:00.0 VGA compatible controller [0300]: NVIDIA Corporation GK107 [GeForce GT 630 OEM] [10de:0fc2] (rev a1) (prog-if 00 [VGA controller])
Subsystem: Micro-Star International Co., Ltd. [MSI] Device [1462:275c]
Flags: bus master, fast devsel, latency 0, IRQ 46
Memory at f6000000 (32-bit, non-prefetchable) [size=16M]
Memory at e0000000 (64-bit, prefetchable) [size=256M]
Memory at f0000000 (64-bit, prefetchable) [size=32M]
I/O ports at e000 [size=128]
Expansion ROM at f7000000 [disabled] [size=512K]
Capabilities: <access denied>
Kernel driver in use: nouveau
可以看到显卡系列是GeForce GT 630 OEM
访问Nvidia官方网址,输入显卡类型,点击search按钮,则会显示需要安装的驱动版本。
Version: 340.58
Release Date: 2014.11.5
Operating System: Linux 64-bit
Language: English (US)
File Size: 69.00 MB
运行以下命令更新源:
sudo add-apt-repository ppa:xorg-edgers/ppa -y
sudo apt-get update
运行以下命令安装驱动:
sudo apt-get install nvidia-340
运行以下命令:
lspci -vnn | grep -i VGA 12
输出
01:00.0 VGA compatible controller [0300]: NVIDIA Corporation GK107 [GeForce GT 630 OEM] [10de:0fc2] (rev a1) (prog-if 00 [VGA controller])
Subsystem: Micro-Star International Co., Ltd. [MSI] Device [1462:275c]
Flags: bus master, fast devsel, latency 0, IRQ 46
Memory at f6000000 (32-bit, non-prefetchable) [size=16M]
Memory at e0000000 (64-bit, prefetchable) [size=256M]
Memory at f0000000 (64-bit, prefetchable) [size=32M]
I/O ports at e000 [size=128]
Expansion ROM at f7000000 [disabled] [size=512K]
Capabilities: <access denied>
Kernel driver in use: nvidia
可见Kernel driver in user显示使用的内核驱动为nvidia
使用nvidia-settings命令配置驱动。
如果安装驱动导致系统无法启动,需要卸载驱动,运行以下命令:
sudo apt-get purge nvidia*
很多教程说安装了nvidia驱动后需要把nouveau放入黑名单,其实并不需要,因为nvidia驱动会自动把它放入黑名单。 运行以下命令:
grep 'nouveau' /etc/modprobe.d/* | grep nvidia
输出:
/etc/modprobe.d/nvidia-340_hybrid.conf:blacklist nouveau
/etc/modprobe.d/nvidia-340_hybrid.conf:blacklist lbm-nouveau
/etc/modprobe.d/nvidia-340_hybrid.conf:alias nouveau off
/etc/modprobe.d/nvidia-340_hybrid.conf:alias lbm-nouveau off
/etc/modprobe.d/nvidia-graphics-drivers.conf:blacklist nouveau
/etc/modprobe.d/nvidia-graphics-drivers.conf:blacklist lbm-nouveau
/etc/modprobe.d/nvidia-graphics-drivers.conf:alias nouveau off
/etc/modprobe.d/nvidia-graphics-drivers.conf:alias lbm-nouveau off
说明已经把它放到黑名单了,即系统启动时不会自动加载这些模块。
参照英文博客
不知道装了什么东西,终端突然无法输入中文,并且无法显示中文,中文显示为???。我切换其他用户,可以正常工作,并且nautilus中文显示正常,因此可以排除是编码设置问题。于是问题一定在于用户配置。因为我使用的是gnome-terminal,因此可能是这个app的问题。尝试修改profile preferences无果。尝试gconf,该app的配置在~/.gconf/apps/gnome-terminal下,为了还原默认设置,只需要删除gnome-terminal这个目录即可,恢复正常。
mount是linux很常用的命令,用于挂载各种设备(包括本地block设备,NFS,虚拟设备等),umount用于卸载设备。如果挂载一个设备到一个目录中,则通过该目录可以访问设备的文件(必须有权限访问),而原来目录的内容会暂时性隐藏(不会覆盖,卸载后恢复可见)。
mount最常用的使用方式为:
mount device dir
比如 mount /dev/sda1 /mnt
这是mount会自动检测设备的文件系统(如果可能的话,比如fstab,mtab中配置有),如果检测失败,需要指定文件系统类型,使用-t选项指定,比如
mount -t btrfs /dev/sda1 /mnt
/etc/fstab是系统默认挂载的配置,在系统启动时会自动挂载该文件下的设备(设置选项noauto除外。
如果你修改了该文件,你也可以使用 mount -a使系统重新读取该文件进行挂载。
在/etc/mtab会记录当前的挂载状况(在/proc/mounts也记录),当使用mount命令不加任何参数时,默认打印该文件的内容。
你也可以使用-l选项打印当前的挂载状况,使用-t选项过滤打印的文件系统类型。
以前一个设备只能挂载在一个地方,从内核2.4以后,支持把一个目录挂载到另一个目录,这时相当于相同文件内容可以同时有多个访问点(这在chroot中很有用,想想我在新的root中怎么访问/proc /dev目录),使用--bind 或者-B选项挂载目录
比如
mount --bind -t tmpfs /dev/ newDev
mount --bind -t proc /proc newProc
注意使用bind选项只能挂载指定目录下的内容,如果该目录下又有子挂载点,不会自动挂载,使用rbind选项,可以递归挂载,甚至可以挂载/ 到另一个目录中。
比如
mount --rbind -t ext4 / newRoot
不过挂载了就不能卸载了,因为该目录正使用(busy),可以使用lsof命令查看(可以使用--move选项,见以下)。
有时我们不想有人bind,可以使用mount --make-unbindable或者--make-runbindable(递归式)选项设置。比如
mount --make-runbindable /
不能再bind根目录了。
--move选项可以把一个挂载点移动到另一个目录,如
mount --move -t ext4 /mnt /media
-r(或者-o ro)选项指定只读挂载,访问挂载点只能读取内容,不能写,-w(或者-o rw)指定挂载为读写方式,这也是默认方式。
-o 指定挂载选项(多个选项使用逗号分隔),以上已经介绍了ro和rw选项,下面简单介绍下挂载选项:
auto ,再/etc/fstab下指定,使用mount -a时或者系统启动时自动挂载,使用noauto相反。
defaults使用默认挂载选项,相当于rw,suid,dev,exec,auto,nouser,async
dev 说明这是字符设备或者块设备,而不是虚拟设备,相反nodev说明可能是虚拟设备
exec,在挂载点可以执行文件,noexec说明在挂载点上不能执行文件,有一次我在家目录下不小心指定了noexec,写了个c程序,运行./a.out出错,后面发现原来是指定了noexec选项
group 一般文件系统挂载只能root身份才有权限,在fstab下指定group,则属于设备组的用户可以挂载。
owner指定设备的所有者可以挂载,比如某设备属于Mary,则root和Mary都有权限挂载。
remount,重新挂载已经挂载的设备,用于覆盖原来的选项,比如原来的文件系统/dev/sda1是只读的,挂载在/mnt下,则可以使用
mount -o remount,rw /dev/sda1 /mnt 重新挂载,并且可读写。
user 用于fstab文件,任何普通用户都可以挂载该设备。
nouser用于fstab,表明只有root可以挂载,这是默认行为。
还有一些选项,专门针对指定的文件系统,比如ext2的errors。
mount还可以用于挂载loop设备,比如iso镜像,img文件等。此时需要指定文件系统类型(-t)和loop选项,比如
mount -t ext4 -o loop ubuntu.iso /mnt
mount -t iso9660 -o loop ubuntu.iso /mnt
卸载loop设备使用命令losetup -d 或者umount -d
试一下
dd if=/dev/zero of=tmp.img bs=500m count=2
mkfs.ext4 tmp.img
mount -t ext4 tmp.img /mnt
使用mount可以挂载iso文件,但磁盘格式为qcow2则不能直接挂载了,可以查看以前的文章挂载http://krystism.is-programmer.com/posts/47074.html。
有时使用ssh登录远程主机,一直卡着不动,等待很久才跳出输入密码提示。
如果不是网络原因(可以ping下网络是否畅通),可能是由于DNS反向解析问题,可以修改远程主机ssh服务器配置文件/etc/ssh/sshd_config文件,设置UseDNS 为no,重启ssh服务器。
如果debug出现Cannot determine realm for numeric host address而卡住,则修改/etc/ssh/ssh_config(注意不是sshd_config) 为GSSAPIAuthentication no