MK
摩柯社区 - 一个极简的技术知识社区
AI 面试

Bash中的文件与目录操作

2021-02-117.4k 阅读

1. 文件操作基础

1.1 创建文件

在Bash中,创建文件最常用的命令是touch。该命令最初的设计目的是用来更新文件的访问和修改时间戳,但如果指定的文件不存在,它会创建一个空文件。

# 创建一个名为example.txt的空文件
touch example.txt

当你运行上述命令后,如果example.txt文件之前不存在,系统会在当前目录下创建一个空的example.txt文件。如果文件已经存在,touch命令会更新其时间戳。

touch命令还支持同时创建多个文件,只需在命令后列出多个文件名即可:

touch file1.txt file2.txt file3.txt

1.2 写入文件内容

  • 使用echo命令重定向写入 echo命令用于在终端输出文本,结合重定向符号>,可以将输出内容写入文件。例如:
echo "This is a sample text" > output.txt

上述命令会将字符串This is a sample text写入output.txt文件。如果output.txt不存在,系统会创建它;如果文件已存在,原有内容会被覆盖。

如果想在不覆盖原有内容的情况下追加文本,可以使用>>符号:

echo "This is additional text" >> output.txt
  • 使用tee命令写入 tee命令可以从标准输入读取数据,然后将其输出到标准输出以及一个或多个文件中。例如:
echo "Text for both terminal and file" | tee output_tee.txt

上述命令不仅会在终端输出Text for both terminal and file,还会将其写入output_tee.txt文件。同样,tee也支持追加模式,使用-a选项:

echo "Additional text with tee" | tee -a output_tee.txt

1.3 读取文件内容

  • 使用cat命令 cat命令(concatenate的缩写)用于连接文件并打印到标准输出,常用于查看文件内容。例如,要查看example.txt的内容:
cat example.txt

如果文件内容较长,在屏幕上快速滚动而难以阅读,可以结合moreless命令。例如,使用more逐页查看文件内容:

cat example.txt | more

按空格键向下翻页,按回车键向下滚动一行。

使用less命令查看文件,less提供了更强大的功能,如支持搜索等:

cat example.txt | less

less中,输入/后输入关键词可以进行搜索,按n键跳转到下一个匹配项。

  • 使用head和tail命令 head命令用于显示文件的开头几行,默认显示前10行。例如,查看big_file.txt的前5行:
head -n 5 big_file.txt

tail命令则用于显示文件的末尾几行,默认也是10行。查看big_file.txt的最后3行:

tail -n 3 big_file.txt

tail还有一个非常有用的选项-f,用于实时跟踪文件的变化,常用于查看日志文件:

tail -f system.log

system.log文件有新内容写入时,tail -f会实时显示这些新内容。

1.4 删除文件

删除文件使用rm命令(remove的缩写)。例如,删除example.txt文件:

rm example.txt

执行该命令后,example.txt文件会被直接删除,且不会进入回收站(在大多数类Unix系统中)。为了防止误删重要文件,可以使用-i选项,该选项会在删除每个文件前提示确认:

rm -i example.txt

系统会提示rm: remove regular file 'example.txt'?,输入y并回车才会删除文件,输入其他字符则取消删除。

如果要删除多个文件,可以在rm命令后列出多个文件名:

rm file1.txt file2.txt file3.txt

2. 文件属性与权限操作

2.1 查看文件属性

  • 使用ls -l命令 ls命令用于列出目录内容,加上-l选项(长格式)可以显示文件的详细属性信息。例如:
ls -l example.txt

输出类似如下内容:

-rw-r--r-- 1 user group 12 2023-10-01 10:00 example.txt

其中:

  • -rw-r--r--表示文件的权限,第一个字符-表示这是一个普通文件(d表示目录,l表示符号链接等)。接下来的三组字符分别表示文件所有者、所属组以及其他用户的权限,r表示读权限,w表示写权限,x表示执行权限。

  • 1表示文件的硬链接数。

  • user是文件所有者的用户名。

  • group是文件所属的组名。

  • 12表示文件的大小(以字节为单位)。

  • 2023-10-01 10:00是文件的修改时间。

  • example.txt是文件名。

  • 使用stat命令 stat命令提供了更详细的文件状态信息,包括文件的inode编号、设备编号、访问时间等。例如:

stat example.txt

输出内容类似:

  File: ‘example.txt’
  Size: 12          Blocks: 8          IO Block: 4096   regular file
Device: 801h/2049d  Inode: 123456      Links: 1
Access: (0644/-rw-r--r--)  Uid: ( 1000/   user)   Gid: ( 1000/   group)
Access: 2023-10-01 10:00:00.000000000 +0000
Modify: 2023-10-01 10:00:00.000000000 +0000
Change: 2023-10-01 10:00:00.000000000 +0000
 Birth: -

2.2 修改文件权限

使用chmod命令(change mode的缩写)来修改文件的权限。权限可以用两种方式表示:符号模式和数字模式。

  • 符号模式 符号模式使用u(所有者)、g(组)、o(其他用户)、a(所有用户)来指定要修改权限的对象,使用+(添加权限)、-(移除权限)、=(设置权限)操作符,以及r(读)、w(写)、x(执行)权限字符。

例如,给文件所有者添加执行权限:

chmod u+x example.txt

给组用户和其他用户移除写权限:

chmod go-w example.txt
  • 数字模式 数字模式使用三位八进制数字表示权限,每一位分别对应所有者、组用户和其他用户的权限。读权限对应4,写权限对应2,执行权限对应1。例如,权限rw-r--r--用数字模式表示为644,因为所有者权限rw-4 + 2 = 6,组用户权限r--4,其他用户权限r--也是4

要将example.txt的权限设置为755(所有者有读、写、执行权限,组用户和其他用户有读、执行权限):

chmod 755 example.txt

2.3 修改文件所有者和所属组

  • 使用chown命令修改所有者 chown命令(change owner的缩写)用于改变文件的所有者。例如,将example.txt的所有者改为new_user
sudo chown new_user example.txt

通常需要使用sudo(如果当前用户不是root用户)来执行该命令,因为修改文件所有者需要管理员权限。

chown命令还可以同时改变文件的所有者和所属组,格式为chown owner:group file。例如:

sudo chown new_user:new_group example.txt
  • 使用chgrp命令修改所属组 chgrp命令(change group的缩写)专门用于改变文件的所属组。例如,将example.txt的所属组改为new_group
sudo chgrp new_group example.txt

同样,一般需要sudo权限来执行此命令。

3. 目录操作基础

3.1 创建目录

使用mkdir命令(make directory的缩写)来创建目录。例如,在当前目录下创建一个名为new_dir的目录:

mkdir new_dir

mkdir命令支持同时创建多个目录,只需列出多个目录名:

mkdir dir1 dir2 dir3

如果要创建嵌套目录(即包含子目录的目录结构),可以使用-p选项。例如,创建parent_dir/child_dir/grandchild_dir这样的目录结构:

mkdir -p parent_dir/child_dir/grandchild_dir

3.2 进入目录

使用cd命令(change directory的缩写)来进入目录。例如,进入new_dir目录:

cd new_dir

要返回上一级目录,可以使用cd..

cd..

要回到用户的主目录,可以使用cd命令不带参数:

cd

3.3 列出目录内容

  • 使用ls命令 ls命令是列出目录内容的基本命令。在当前目录下,简单运行ls会列出目录中的文件和子目录名:
ls

加上-l选项可以以长格式列出详细信息,如前面介绍查看文件属性时所述。

ls还有许多其他有用的选项,例如-a选项用于列出所有文件,包括隐藏文件(文件名以.开头的文件):

ls -a

-R选项用于递归列出子目录中的内容:

ls -R

3.4 删除目录

使用rmdir命令(remove directory的缩写)来删除空目录。例如,删除new_dir目录(前提是该目录为空):

rmdir new_dir

如果目录不为空,rmdir命令会失败。要删除非空目录及其所有内容,需要使用rm -r命令(-r表示递归删除)。例如,删除parent_dir目录及其所有子目录和文件:

rm -r parent_dir

同样,为了防止误删,可以使用-i选项提示确认:

rm -ri parent_dir

4. 文件与目录的移动、复制和链接操作

4.1 移动文件和目录

使用mv命令(move的缩写)来移动文件或目录。例如,将example.txt文件移动到new_dir目录中:

mv example.txt new_dir/

如果目标路径是一个已存在的目录,文件会被移动到该目录下。如果目标路径是一个文件名,example.txt会被重命名为目标文件名并移动到相应位置。

移动目录的操作类似,例如将old_dir移动到parent_dir目录下:

mv old_dir parent_dir/

mv命令也可以用于重命名文件或目录。例如,将old_file.txt重命名为new_file.txt

mv old_file.txt new_file.txt

4.2 复制文件和目录

使用cp命令(copy的缩写)来复制文件。例如,将example.txt复制为example_copy.txt

cp example.txt example_copy.txt

要将文件复制到另一个目录,例如将example.txt复制到new_dir目录中:

cp example.txt new_dir/

复制目录需要使用-r选项(递归复制)。例如,将source_dir目录及其所有内容复制到destination_dir目录中:

cp -r source_dir destination_dir/

cp命令还有一些其他有用的选项,如-i选项在覆盖目标文件前提示确认,-p选项保留源文件的属性。

4.3 创建链接

在Bash中有两种类型的链接:硬链接和符号链接。

  • 硬链接 使用ln命令创建硬链接。例如,为example.txt创建一个硬链接hard_link.txt
ln example.txt hard_link.txt

硬链接和源文件共享相同的inode编号,它们实际上是同一个文件的不同名称。对其中一个文件的修改会立即反映在另一个文件上,并且删除其中一个文件不会影响另一个文件,除非所有硬链接都被删除。

硬链接有一些限制,例如不能跨文件系统创建硬链接,也不能为目录创建硬链接。

  • 符号链接 使用ln -s选项创建符号链接(软链接)。例如,为example.txt创建一个符号链接soft_link.txt
ln -s example.txt soft_link.txt

符号链接是一个指向源文件的特殊文件,它有自己的inode编号。符号链接可以跨文件系统,也可以为目录创建。如果源文件被删除,符号链接将指向一个不存在的文件,成为“断链”。

5. 高级文件与目录操作技巧

5.1 通配符的使用

通配符是一种在文件名或目录名中使用的特殊字符,用于匹配多个文件或目录。

  • 星号(*)通配符 *通配符匹配零个或多个任意字符。例如,要列出当前目录下所有以.txt结尾的文件:
ls *.txt

要删除当前目录下所有文件(不包括隐藏文件):

rm *
  • 问号(?)通配符 ?通配符匹配单个任意字符。例如,要列出文件名是四个字符且以.txt结尾的文件:
ls????.txt
  • 方括号([])通配符 方括号内可以指定一个字符范围或字符集合。例如,要列出文件名以ac开头且以.txt结尾的文件:
ls [a - c]*.txt

要列出文件名包含aeiou中任意一个字符且以.txt结尾的文件:

ls *[aeiou]*.txt

5.2 查找文件和目录

  • 使用find命令 find命令是一个非常强大的文件查找工具。例如,在当前目录及其所有子目录中查找名为example.txt的文件:
find. -name example.txt

其中.表示当前目录,-name选项用于按文件名查找。

要查找大于100KB的文件:

find. -size +100k

-size选项用于按文件大小查找,+100k表示大于100KB,-100k表示小于100KB。

要查找在过去24小时内修改过的文件:

find. -mmin -1440

-mmin选项用于按文件的修改时间查找,-1440表示在过去1440分钟(24小时)内修改过。

find命令还可以结合-exec选项对找到的文件执行命令。例如,对找到的所有.txt文件执行chmod 644命令:

find. -name "*.txt" -exec chmod 644 {} \;

{}表示找到的文件名,\;表示命令结束。

  • 使用locate命令 locate命令通过搜索文件数据库来查找文件,速度比find命令快,但它依赖于数据库的更新。数据库通常由系统定时更新(例如每天一次)。

例如,查找所有包含example的文件:

locate example

要更新数据库,可以使用sudo updatedb命令(需要管理员权限)。

5.3 处理特殊文件类型

  • 设备文件 设备文件是与硬件设备相关的文件,位于/dev目录下。例如,/dev/sda通常表示第一个SATA硬盘。在Bash中,可以像操作普通文件一样对设备文件进行读写操作(需要适当的权限),但需要注意操作设备文件可能会对硬件设备产生影响。

  • 管道文件(FIFO) FIFO(命名管道)是一种特殊的文件类型,用于进程间通信。可以使用mkfifo命令创建FIFO文件。例如:

mkfifo my_fifo

一个进程可以向FIFO文件写入数据,另一个进程可以从FIFO文件读取数据,从而实现进程间的数据传输。

5.4 批量处理文件与目录

在Bash中,可以使用循环和脚本对文件和目录进行批量处理。

  • 使用for循环批量处理文件 例如,要将当前目录下所有.txt文件的权限设置为600
for file in *.txt; do
    chmod 600 "$file"
done

上述代码中,for循环遍历所有以.txt结尾的文件,dodone之间的命令会对每个文件执行。

  • 编写脚本进行复杂批量处理 可以将一系列文件和目录操作编写成脚本。例如,创建一个名为batch_operations.sh的脚本,用于在指定目录及其子目录中查找所有.log文件,并将其复制到backup目录中:
#!/bin/bash

if [ $# -ne 1 ]; then
    echo "Usage: $0 directory"
    exit 1
fi

source_dir=$1
backup_dir=backup

mkdir -p "$backup_dir"

find "$source_dir" -name "*.log" -exec cp {} "$backup_dir" \;

在上述脚本中,首先检查是否提供了一个参数(指定的源目录),如果没有则提示用法并退出。然后创建backup目录(如果不存在),最后使用find命令查找所有.log文件并复制到backup目录中。

要运行该脚本,首先需要给脚本添加执行权限:

chmod +x batch_operations.sh

然后运行脚本,例如:

./batch_operations.sh /var/log