>  기사  >  시스템 튜토리얼  >  초보자부터 숙련자까지 Linux 리디렉션 및 파이프라인 도구를 배워 작업 흐름 속도를 높이세요!

초보자부터 숙련자까지 Linux 리디렉션 및 파이프라인 도구를 배워 작업 흐름 속도를 높이세요!

PHPz
PHPz앞으로
2024-02-09 23:36:381202검색

업무 효율성 향상, 운영 체제 최적화, 자동화 등은 모든 IT 실무자가 추구하는 목표입니다. Linux 운영 체제에서는 리디렉션 및 파이프라인 명령줄 도구를 능숙하게 사용할 수 있는 능력이 숙달되어야 하는 기술 중 하나입니다. 이 문서에서는 예제를 통해 리디렉션 및 파이프라인 도구의 사용법과 원리를 자세히 설명합니다.

저는 Linux 시스템을 매우 좋아합니다. 특히 Linux의 일부 디자인은 매우 아름답습니다. 예를 들어 일부 복잡한 문제는 여러 개의 작은 문제로 분해될 수 있고 파이프 문자 및 리디렉션을 통해 기성 도구를 사용하여 유연하게 해결할 수 있습니다. 메커니즘. 쉘 스크립트를 작성하는 것은 매우 효율적입니다.

초보자부터 숙련자까지 Linux 리디렉션 및 파이프라인 도구를 배워 작업 흐름 속도를 높이세요!

이 기사에서는 실제로 리디렉션 및 파이프 문자를 사용할 때 직면한 몇 가지 함정을 공유할 것입니다. 몇 가지 기본 원칙을 이해하면 스크립트 작성 효율성이 크게 향상될 수 있습니다.

> 및 >> 리디렉션 문자

의 함정

먼저 첫 번째 질문부터 이야기해 보겠습니다. 다음 명령을 실행하면 어떻게 될까요?

으아악

같은 파일을 읽고 쓰면 아무 일도 일어나지 않을 것 같죠?

실제로 위 명령을 실행한 결과는 file.txt 파일의 내용이 지워지는 것입니다.

PS: 일부 Linux 배포판에서는 catfile.txt를 실행하여 이 감지를 우회할 수 있습니다.

Linux 프로세스 및 파일 설명자에 대한 이전 기사에서 언급한 것처럼 프로그램 자체는 표준 입력/출력 지점이 어디인지 신경 쓸 필요가 없습니다. 리디렉션 기호.

따라서 cat file.txt > file.txt 명령을 실행하면 쉘은 먼저 file.txt를 엽니다. 리디렉션 기호가 >이므로 파일 내용이 지워진 다음 쉘은 다음의 표준 출력을 설정합니다. cat 명령을 .txt 파일로 전송하면 cat 명령이 실행되기 시작합니다.

즉, 다음과 같은 과정이 있습니다:

1. 쉘은 file.txt를 열고 내용을 지웁니다.
2. 쉘은 cat 명령의 표준 출력을 file.txt 파일로 지정합니다.
3. 쉘은 cat 명령을 실행하고 빈 파일을 읽습니다.
4. cat 명령은 표준 출력(file.txt 파일)에 빈 문자열을 씁니다.

그래서 최종 결과는 file.txt가 빈 파일이 되는 것입니다.

우리는 > ​​대상 파일을 지우고 >>가 대상 파일 끝에 내용을 추가한다는 것을 알고 있으므로 리디렉션 기호 >가 >>?로 변경되면 어떻게 될까요?

으아악

먼저 file.txt에 한 줄의 내용이 기록됩니다. cat file.txt >> file.txt를 실행한 후 예상되는 결과는 두 줄의 내용이어야 합니다.

하지만 안타깝게도 실행 결과는 예상과 다릅니다. 대신 무한 루프에서 file.txt에 계속해서 hello world를 작성하게 되며, 파일은 곧 매우 커질 것이며 Ctrl+C로만 명령을 중지할 수 있습니다.

흥미롭네요. 무한 루프가 존재하는 이유는 무엇일까요? 사실 약간의 분석을 통해 그 이유를 생각해 볼 수 있습니다.

먼저 cat 명령의 동작을 기억해 보세요. cat 명령만 실행하면 Enter 키를 누를 때마다 키보드 입력이 읽혀집니다. cat 명령은 하나씩 데이터를 읽은 다음 출력합니다.

이후 cat file.txt >> file.txt 명령의 실행 과정은 다음과 같습니다.

1. file.txt를 열고 파일 끝에 내용을 추가할 준비를 합니다.
2. cat 명령의 표준 출력이 file.txt 파일을 가리키도록 합니다.
3. cat 명령은 file.txt의 내용 한 줄을 읽고 이를 표준 출력에 씁니다(file.txt 파일에 추가).
4. 방금 데이터 줄이 기록되었으므로 cat 명령은 file.txt에 아직 읽을 수 있는 내용이 있음을 확인하고 3단계를 반복합니다.

위 프로세스는 목록을 순회하는 동시에 목록에 요소를 추가하는 것과 같습니다. 완전히 순회할 수 없으므로 명령이 무한 루프로 이어집니다.

> 리디렉션 문자와 | 파이프 문자가 함께 작동합니다

파일의 처음 XX줄을 가로채서 나머지 부분을 삭제해야 하는 경우가 종종 있습니다.

Linux에서 head 명령은 파일의 처음 몇 줄을 가로채는 기능을 완료할 수 있습니다.

으아악

파일의 처음 두 줄을 유지하고 나머지 줄을 삭제하려면 다음 명령을 사용할 수 있습니다.

으아악

그러나 이렇게 하면 위에서 언급한 실수가 발생하게 되어 결국 file.txt가 지워져 우리의 요구 사항을 충족할 수 없게 됩니다.

그러면 다음과 같이 명령을 작성하면 함정을 피할 수 있을까요?

으아악

결론은 작동하지 않으며 파일 내용은 여전히 ​​지워진다는 것입니다.

파이프라인에 누출이 있어서 모든 데이터가 손실되나요?

Linux 프로세스 및 파일 설명자에 대한 이전 기사에서 파이프 문자의 구현 원리에 대해서도 언급했습니다. 기본적으로 두 명령의 표준 입력과 출력을 연결하여 이전 명령의 표준 출력이 표준 입력 역할을 합니다. 다음 명령의.

그러나 이렇게 명령을 작성하면 예상한 결과를 얻을 수 있다고 생각한다면 파이프 문자로 연결된 명령이 순차적으로 실행된다고 생각하기 때문일 수 있습니다. 실제로 여러 명령이 파이프로 연결되는 경우가 많습니다. 문자가 병렬로 실행됩니다.

셸이 먼저 cat file.txt 명령을 실행하고 정상적으로 file.txt의 모든 내용을 읽은 다음 이 내용을 파이프를 통해 head -n 2 > file.txt 명령에 전달한다고 생각할 수도 있습니다.

이때 file.txt의 내용은 지워지지만 head는 파일에서 데이터를 읽지 않고 파이프에서 데이터를 읽으므로 file.txt에 두 줄의 데이터를 올바르게 쓰는 것이 가능할 것입니다.

但实际上,上述理解是错误的,shell 会并行执行管道符连接的命令,比如说执行如下命令:

$ sleep 5 | sleep 5 

shell 会同时启动两个sleep进程,所以执行结果是睡眠 5 秒,而不是 10 秒。

这是有点违背直觉的,比如这种常见的命令:

$ cat filename | grep 'pattern' 

直觉好像是先执行cat命令一次性读取了filename中所有的内容,然后传递给grep命令进行搜索。

但实际上是cat和grep命令是同时执行的,之所以能得到预期的结果,是因为grep ‘pattern’会阻塞等待标准输入,而cat通过 Linux 管道向grep的标准输入写入数据。

执行下面这个命令能直观感受到cat和grep是在同时执行的,grep在实时处理我们用键盘输入的数据:

$ cat | grep 'pattern' 

说了这么多,再回顾一开始的问题:

$ cat file.txt | head -n 2 > file.txt 

cat命令和head会并行执行,谁先谁后不确定,执行结果也就不确定。

如果head命令先于cat执行,那么file.txt就会被先清空,cat也就读取不到任何内容;反之,如果cat先把文件的内容读取出来,那么可以得到预期的结果。

不过,通过我的实验(将这种并发情况重复 1w 次)发现,file.txt被清空这种错误情况出现的概率远大于预期结果出现的概率,这个暂时还不清楚是为什么,应该和 Linux 内核实现进程和管道的逻辑有关。

解决方案

说了这么多管道符和重定向符的特点,如何才能避免这个文件被清空的坑呢?

最靠谱的办法就是不要同时对同一个文件进行读写,而是通过临时文件的方式做一个中转。

比如说只保留file.txt文件中的头两行,可以这样写代码:

# 先把数据写入临时文件,然后覆盖原始文件

$ cat file.txt | head -n 2 > temp.txt && mv temp.txt file.txt

这是最简单,最可靠,万无一失的方法。

你如果嫌这段命令太长,也可以通过apt/brew/yum等包管理工具安装moreutils包,就会多出一个sponge命令,像这样使用:

# 先把数据传给 sponge,然后由 sponge 写入原始文件 
$ cat file.txt | head -n 2 | sponge file.txt 

sponge这个单词的意思是海绵,挺形象的,它会先把输入的数据「吸收」起来,最后再写入file.txt,核心思路和我们使用临时文件时类似的,这个「海绵」就好比一个临时文件,就可以避免同时打开同一个文件进行读写的问题。

在Linux操作系统中,重定向和管道是非常有用的命令行工具,可以让我们更好地掌握系统的运行状态和信息。掌握相关技能能够帮助我们更好地进行系统优化和自动化工作,从而更好地提高工作效率。相信通过本文的介绍,读者对重定向和管道的原理和使用方法都有了更为深入的了解。

위 내용은 초보자부터 숙련자까지 Linux 리디렉션 및 파이프라인 도구를 배워 작업 흐름 속도를 높이세요!의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 lxlinux.net에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제