生猛干货
从系统安装到程序员必备的Linux技能,还原真实工作场景,手把手带你实战演练
概述
你有将Linux物尽其用吗?有些时候你会需要这些技巧。本博文会帮助你更好得使用一些命令,发挥其更强大的功能。
命令行小技巧
history命令来查看曾经运行过的命令
# history
history中显示命令的执行时间
从history命令输出看,很明显,命令的执行时间没有被打出来。有解决方法吗?有的!运行如下命令:
# HISTTIMEFORMAT="%d/%m/%y %T " # history
如果你想让这个修改永久生效,添加如下的一行内容到~/.bashrc文件中:
export HISTTIMEFORMAT="%d/%m/%y %T " 或者 export HISTTIMEFORMAT="%y-%m-%d %T "
格式自定义即可
然后,在终端中运行:
# source ~/.bashrc
命令和选项的解释:
history – 查看运行过的命令 HISTIMEFORMAT – 设置时间格式的环境变量 %d – 天 %m – 月 %y – 年 %T – 时间戳 source – 简而言之就是将文件内容发送给shell来执行 .bashrc – BASH以交互方式启动时运行的脚本文件
清除history
- 在命令前插入空格
是的,没看错。在命令前面插入空格,这条命令会被 shell 忽略,也就意味着它不会出现在历史记录中。但是这种方法有个前提,只有在你的环境变量 HISTCONTROL 设置为 “ignorespace” 或者 “ignoreboth” 才会起作用。在大多数情况下,这个是默认值。
所以,像下面的命令
[space]echo "this is a top secret"
如果你之前执行过如下设置环境变量的命令,那么上述命令不会出现在历史记录中。
export HISTCONTROL=ignorespace
- 禁用当前会话的所有历史记录
如果你想禁用某个会话所有历史,你可以在开始命令行工作前简单地清除环境变量 HISTSIZE 的值即可。执行下面的命令来清除其值:
export HISTSIZE=0
HISTSIZE 表示对于 bash 会话其历史列表中可以保存命令的个数(行数)。默认情况,它设置了一个非零值,
查看默认值
[root@entel2 ~]# echo $HISTSIZE 1000
- 工作结束后清除整个历史
这可以看作是前一部分所提方案的另外一种实现。唯一的区别是在你完成所有工作之后执行这个命令。下面是刚说到的命令:
history -cw
刚才已经提到,这个和 HISTSIZE 方法有相同效果。
- 只针对你的工作关闭历史记录
虽然前面描述的方法(2 和 3)可以实现目的,它们可以清除整个历史,在很多情况下,有些可能不是我们所期望的。有时候你可能想保存直到你开始命令行工作之间的历史记录。对于这样的需求,你开始在工作前执行下述命令:
[space]set +o history
备注:[space] 表示空格。并且由于空格的缘故,该命令本身也不会被记录。
上面的命令会临时禁用历史功能,这意味着在这命令之后你执行的所有操作都不会记录到历史中,然而这个命令之前的所有东西都会原样记录在历史列表中。
要重新开启历史功能,执行下面的命令:
[Space]set -o history
它将环境恢复原状,也就是你完成了你的工作,执行上述命令之后的命令都会出现在历史中。
- 从历史记录中删除指定的命令
现在假设历史记录中已经包含了一些你不希望记录的命令。这种情况下我们怎么办?很简单。直接动手删除它们。通过下面的命令来删除:
history | grep "part of command you want to remove"
上面的命令会输出历史记录中匹配的命令,每一条前面会有个数字。
一旦你找到你想删除的命令,执行下面的命令,从历史记录中删除那个指定的项:
history -d [num]
- 其他
cat | bash #执行这条命令后可以直接在其之后执行其他命令,除了这条命令不会留下其他目录的历史,Tab键功能不能用
echo > ~/.bash_history #清除当前用户所有记录到文件里的记录
history -c #清楚所有历史纪录,不能清除文件里的
history -d {n} #清除历史纪录中指定的某条记录,{n}为数字
history -d {n} && history -d {x} && history -d {y} #清除指定的多条记录,包括可以清除自身这条
for i in {99…233}; do history -d $i; done #使用for循环清除指定连续的多条命令
获取吃掉你磁盘空间的最大的5个文件
一个使用du命令的简单单行脚本即可实现,du命令主要用于获取文件的空间使用情况。
# du -hsx * | sort -rh | head -5
命令和选项的解释:
- du – 估计文件的空间使用情况
- -hsx – (-h)更易读的格式,(-s)汇总输出,(-x)跳过其他文件系统的文件
- sort – 对文本文件按行排序
- -rh – (-r)将比较的结果逆序输出,(-h) for compare human readable format.
- head – 输出文件的头几行
注意: 只能获取当前目录下,不能递归子目录。
获取一个文件的详细状态信息
可以使用stat命令
# stat filename_ext (例如:stat abc.pdf)
随机显示一个man手册页
# man $(ls /bin | shuf | head -1)
命令和选项的解释:
man – Linux man手册 ls – 列出文件 /bin – 系统可执行文件的路径 shuf – 把输入内容按行随机打乱并输出 head – 输出文件的头几行
删除大文件
有时候文件可能会变得很大。我看过由于缺乏管理技能一个日志文件就超过 250G 的例子。用 rm 命令可能不足以删除该文件,因为有大量的数据需要移除。应该避免这个很“笨重”的操作。相反,你可以使用一个简单的方法解决这个问题:
# > /path-to-file/huge_file.log
当然你需要根据你实际情况替换路径和文件名。上面的命令写一个空输出到该文件。用更简单的话说它会清空文件而不会导致你的系统产生大的 I/O 消耗。
复制文件到多个目录
通常使用 cp 命令进行文件复制。复制文件通常看起来类似:
# cp /path-to-file/my_file.txt /path-to-new-directory/
现在假设你需要复制该文件到多个目录:
# cp /home/user/my_file.txt /home/user/1 # cp /home/user/my_file.txt /home/user/2 # cp /home/user/my_file.txt /home/user/3
这有点荒唐。相反,你可以用简单的一行命令解决问题:
# echo /home/user/1/ /home/user/2/ /home/user/3/ | xargs -n 1 cp /home/user/my_file.txt
在多个 Linux 服务器上运行相同命令
将服务器的 IP 地址写到文件 list.txt 中,像上面那样一行一个。然后运行:
# for in $i(cat list.txt); do ssh user@$i 'bash command'; done
上面的命令中你需要用实际登录的用户替换 “user”,用你希望执行的实际命令替换 “bash command”。这个方法非常适用于通过使用 SSH 密钥进行无密码验证,因为这样你不需要每次都为用户输入密码。
注意取决于你 Linux 系统的设置,你可能还需要传递一些额外的参数给 SSH 命令。
在指定时间关闭计算机
有时候你需要在下班几个小时后再关闭计算机。你可以通过使用下面的命令在指定时间关闭你的计算机:
$ sudo shutdown 21:00
这会告诉你在你指定的时间关闭计算机。你也可以告诉系统在指定分钟后关闭:
$ sudo shutdown +15
这表示计算机会在 15 分钟后关闭。
用一个命令创建目录树
你很可能知道可以使用 mkdir 命令创建新的目录。因此如果你想创建一个新的目录,你可能会运行:
# mkdir new_folder
但如果你想在该目录下创建 5 个子目录呢?运行 5 次 mkdir 命令并非是一个好的选择。相反你可以类似下面这样使用 -p 选项:
# mkdir -p new_folder/{folder_1,folder_2,folder_3,folder_4,folder_5}
最后你会在 new_folder 中有 5 个目录:
# ls new_folder/ folder_1 folder_2 folder_3 folder_4 folder_5
假设你要创建一个类似于下面很长的/复杂的目录树。实现这最有效的方法是什么呢?
类似下面要实现的目录树结构。
$ cd /home/$USER/Desktop $ mkdir tecmint $ mkdir tecmint/etc $ mkdir tecmint/lib $ mkdir tecmint/usr $ mkdir tecmint/bin $ mkdir tecmint/tmp $ mkdir tecmint/opt $ mkdir tecmint/var $ mkdir tecmint/etc/x1 $ mkdir tecmint/usr/x2 $ mkdir tecmint/usr/x3 $ mkdir tecmint/tmp/Y1 $ mkdir tecmint/tmp/Y2 $ mkdir tecmint/tmp/Y3 $ mkdir tecmint/tmp/Y3/z
上述情况可以简单地通过运行下面一行命令来实现。
$ mkdir -p /home/$USER/Desktop/tecmint/{etc/x1,lib,usr/{x2,x3},bin,tmp/{Y1,Y2,Y3/z},opt,var}
你可以用 tree 命令验证。如果没有安装你可以使用 apt 或 yum 安装 ‘tree’ 软件包。
$ tree tecmint
我们可以用上面的方式创建任意复杂的目录树结构。注意这仅仅是一个普通的命令,但是用 ‘{}’ 来创建层级目录。需要的时候如果在 shell 脚本中使用是非常有用的。
执行之前的命令
很多时候你需要一遍又一遍执行相同的命令。尽管你可以重复按你键盘上的向上光标键,但你也可以用 history 命令替代。这个命令会列出自从你上次启动终端以来所有输入过的命令:
# history
正如你上面看到的,你会得到一个你运行过的命令的列表。每一行中有一个数字表示你在第几行输入了命令。你可以通过以下方法重新调用该命令:
!#
其中要用命令的实际编号代替 #。
在 Linux 中锁定或隐藏文件或目录
锁定文件或目录最简单的方法是使用 Linux 文件权限。如果你是文件或目录的所有者,你可以阻止其他用户和组访问(删除、读取、写入、执行)它,如下所示:
$ chmod 700 xgj.info 或 $ chmod go-rwx xgj.info
为了实现对系统中的其他用户隐藏文件或目录,可以通过在文件或目录开头添加 . 的方式重命名:
$ mv filename .filename
##当 sudo 命令执行失败时怎么使用 su 命令
虽然 sudo 命令被用来以超级用户权限执行命令,但是在某些情况下它也会执行失败,如下所示。
在这里,我想清空一个大文件的内容,其文件名为 uptime.log,但是即便我是使用 sudo 命令也执行失败了。
$ cat /dev/null >/var/log/uptime.log $ sudo cat /dev/null >/var/log/uptime.log
遇到这种情况,你需要使用 su 命令切换到 root 用户,然后像下面这样去执行清空操作:
$ su $ sudo cat /dev/null >/var/log/uptime.log $ cat /var/log/uptime.log
##在 Linux 中永久删除文件
一般情况下,我们通过使用 rm 命令将文件从 Linux 系统中删除。然而,这些文件并没有被真正的删除,它们仍被存储在那里并隐藏在你的硬盘中,其他用户仍然可以在 Linux 中恢复删除的文件并查看。
为了防止这种情况发生,我们可以使用 shred 命令来覆写文件内容,并在覆盖完成后选择删除文件。
$ shred -zvu xgj.tar
上述命令中所使用的选项说明:
-z – 最后一次使用 0 进行覆盖以隐藏覆写动作。 -u – 覆写后截断并移除文件。 -v – 显示详细过程。
阅读 shred 手册以获取更多的使用信息。
$ man shred
##在 Linux 中重命名多个文件
你可以通过使用 rename 命令随时在 Linux 中重命名多个文件。
rename 命令会根据第一个参数中的规则重命名指定文件。
以下命令会将所有 .pdf 文件重命名为 .doc 文件,使用的规则为 ‘s/.pdf$/.doc/’:
$ rename -v 's/\.pdf$/\.doc/' *.pdf
在 Linux 中检查单词拼写
look 命令用于显示文件中以指定字符串为前缀的任意行,同时它也可以帮你检查命令行中给定单词的拼写。尽管它并不是那么有效和可靠,但它仍然算得上是其他强大的拼写检查工具的有用替代品。
$ look linu $ look docum
列出所有 Shell 内置命令
shell 内置命令是一个命令或者函数,从内部调用并直接在 shell 里执行,而不是从硬盘加载外部的可执行程序来执行。
列出所有 shell 内置命令及其语法,执行如下命令:
$ help
如何在不使用Cron的情况调度Linux下的任务
在Linux下,调度一个任务/命令称之为Cron。当我们需要调度一个任务时,我们会使用Cron,但你知道我们在不使用Cron的情况也可以调度一个在将来时间运行的任务吗?你可以按照如下建议操作……
每5秒钟运行一个命令(date)然后将结果写入到一个文件(data.txt)。为了实现这一点,我们可以直接在命令提示符运行如下单行脚本。
$ while true; do date >> date.txt ; sleep 5 ; done &
上述脚本的解释:
while true :让脚本进入一个条件总为真的循环中,也就是制造一个死循环,将里边的命令一遍遍地重复运行。 do :do是while语句中的关键字,它之后的命令会被执行,在它后边可以放置一个或一系列命令。 date >> date.txt :运行date命令,并将其输出写入到data.txt文件中。注意我们使用>>,而不是>。 >> :对文件(date.txt)进行追加写的操作,这样每次运行命令后,输出内容会被追加到文件中。如果使用>的话,则会一遍遍地覆盖之前的内容。 > done :while循环语句块结束的标记。 & :将整个进程放到后台运行。
类似地,我们可以这样运行任何脚本。下边的例子是每100秒运行一个名为script_name.sh的脚本。
另外值得一提的是上面提到的脚本文件必须处于当前目录中,否则需要使用完整路径(/home/$USER/…/script_name.sh)。实现如上功能的单行脚本如下:
$ while true; do /bin/sh script_name.sh ; sleep 100 ; done &
总结:上述的单行脚本并不是Cron的替代品,因为Cron工具支持众多选项,更加灵活,可定制性也更高。然而如果我们想运行某些测试,比如I/O评测,上述的单行脚本也管用。
如何不使用clear命令清空终端的内容
你如何清空终端的内容?你可能会认为这是一个傻问题。好吧,大家都清楚可以使用clear命令。如果养成使用ctrl + l快捷键的习惯,我们会节省大量时间。
Ctrl + l快捷键的效果和clear命令一样。所以下一次你就可以使用ctrl + l来清空终端的内容了。
总结:因为ctrl + l是一个快捷键,我们不可以在脚本中使用。所以如果我们需要在脚本中清空屏幕内容,还是需要使用clear命令。但我能想到的所有其他情况,ctrl + l都更加有效。
在其它目录运行一个命令,然后自动返回当前工作目录
这是一个很多人可能不知道的令人吃惊的技巧。你可能想在其它目录运行任何一个命令,然后再回到当前目录。要实现这样的目的,你只需要将命令放在一个圆括号里。
[root@entel2 ~]# pwd /root [root@entel2 ~]# (cd /docker/ && ll) total 60 drwxr-xr-x 5 root root 4096 Jun 15 2016 aufs drwx------ 9 root root 4096 Jan 19 15:55 containers ...... [root@entel2 ~]# pwd /root [root@entel2 ~]#
相当于在里面创建了个子shell,里面的命令执行完后自动退出子shell,故不改变当前工作目录。
在桌面(/home/$USER/Desktop)创建一个文件(例如 test)并填入以下内容。
ABC DEF GHI JKL MNO PQR STU VWX Y Z
这种情况一个普通用户会怎么做呢?
a. 他首先会创建文件,最好使用 touch 命令,例如:
$ touch /home/$USER/Desktop/test
b. 他会用一个文本编辑器打开文件,这可能是 nano、vim 或其它编辑器。
$ vim /home/$USER/Desktop/test
c. 然后他会将上面的内容输入到文件中,保存并退出。
忽略他/她使用的时间,他至少需要 3 步来执行上面的情况。
一个经验丰富的 Linux 用户会怎么做呢?他会在终端中输入下面的文本然后就完成所有任务。他不需要单独执行每一步。
cat << EOF > /home/$USER/Desktop/test ABC DEF GHI JKL MNO PQR STU VWX Y Z EOF
Tar 包解压到指定位置
$ tar -jxvf firefox-37.0.2.tar.bz2 -C /opt/
-C 选项提取文件到指定目录(这里是 /opt/)。