文章目录


​history命令来查看曾经运行过的命令​


生猛干货

​从系统安装到程序员必备的Linux技能,还原真实工作场景,手把手带你实战演练​

Linux 命令行小技巧-持续更新_历史记录


概述

你有将Linux物尽其用吗?有些时候你会需要这些技巧。本博文会帮助你更好得使用一些命令,发挥其更强大的功能。

Linux 命令行小技巧-持续更新_bash_02


命令行小技巧

history命令来查看曾经运行过的命令

# history

history中显示命令的执行时间

从history命令输出看,很明显,命令的执行时间没有被打出来。有解决方法吗?有的!运行如下命令:

# HISTTIMEFORMAT="%d/%m/%y %T "
# history

Linux 命令行小技巧-持续更新_命令行小技巧_03

如果你想让这个修改永久生效,添加如下的一行内容到~/.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

Linux 命令行小技巧-持续更新_命令行小技巧_04

我们可以用上面的方式创建任意复杂的目录树结构。注意这仅仅是一个普通的命令,但是用 ‘{}’ 来创建层级目录。需要的时候如果在 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

Linux 命令行小技巧-持续更新_历史记录_05

遇到这种情况,你需要使用 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

Linux 命令行小技巧-持续更新_linux_06


列出所有 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/)。