Shell里面的&符号、>符号的细节理解
1、问题1
当我在Linux用screen来管理服务时,由于输入的命令最后 多了个 &,
导致在screen -ls 查看返回结果中,一直都找不到刚才启动的服务。
最后才发现是这个 “&” 的缘故。
screen -S filescompare 后
正确的的命令应当是:
uvicorn your_app:app --reload --host 0.0.0.0 --port 9000 > uvicorn.log 2>&1
而我输入的命令最后多了个 &
uvicorn your_app:app --reload --host 0.0.0.0 --port 9000 > uvicorn.log 2>&1 &
因为在命令末尾加了 &。我来解释一下这个差异。
& 和 screen 的关系
-
&:这是 Shell 命令中的一个特殊符号,表示将命令放到后台执行。当你在命令末尾加上&,Shell 会在后台启动该进程并立即返回到命令行。虽然进程会继续在后台运行,但它不再与当前的 shell 会话关联。这意味着,如果你退出当前的 shell,后台进程也会受到影响,可能会被杀死。 -
screen:screen是一个终端复用工具,它可以将进程与当前终端会话分离(通过Ctrl+A + D)。分离后,进程继续在后台运行,但它会一直与screen会话关联,即使你关闭终端或退出,进程依然会持续运行,直到你明确结束它。通过screen -ls可以查看当前活动的会话,使用screen -r可以恢复这些会话。
你遇到的问题
- 当你使用
&来后台运行命令时,进程会在后台运行,但由于没有使用screen,这个进程就没有与一个持久的终端会话关联。 - 由于没有
screen会话,screen -ls不会显示任何内容,即使进程本身在后台通过lsof可以看到它在监听端口。
解决方案
如果你希望通过 screen 来管理进程,避免使用 & 将其放到后台,应该通过以下方式操作:
1. 通过 screen 启动服务:
在启动服务时,不要加上 &,直接在 screen 会话中启动命令。这样可以确保进程与 screen 会话关联,即使退出终端,进程仍会在后台持续运行,并且能够通过 screen -ls 查看和恢复。
screen -S filescompare
uvicorn your_app:app --reload --host 0.0.0.0 --port 9000 > uvicorn.log 2>&1
2.分离 screen 会话:
一旦服务启动,在 screen 会话中按下 Ctrl + A,然后按 D 来分离会话。此时进程将继续在后台运行
3.查看 screen 会话:
使用 screen -ls 查看当前的 screen 会话,并可以恢复到该会话。
screen -ls
4.恢复 screen 会话:
如果你退出并希望重新进入会话,可以使用 screen -r <session_name> 或者通过会话ID(如 filescompare)来恢复。
screen -r filescompare
总结
- 使用
screen时 不要加&,因为screen本身已经负责在后台管理进程,并保持进程与会话的关联。 - 使用
screen可以让你管理进程,即使退出终端或断开连接,进程仍然会继续运行。
2、问题2
对于如下命令,如何理解各参数的含义,尤其最后几个。
nohup uvicorn your_app:app --reload --host 0.0.0.0 --port 9000 > uvicorn.log 2>&1 &
1. nohup
nohup是 no hang up 的缩写,表示“忽略挂起信号”。- 它用于确保命令在退出当前会话(比如关闭终端)后依然继续执行。通常,终端会向正在运行的进程发送
SIGHUP(挂起信号)来终止进程,但使用nohup后,进程会忽略这个信号,继续在后台运行。 - 使用
nohup可以确保在关闭终端或断开 SSH 连接时,进程仍然可以继续运行,直到被明确终止。
2. uvicorn your_app:app
uvicorn是一个轻量级的 ASGI 服务器(Asynchronous Server Gateway Interface),常用于运行 FastAPI 应用。uvicorn用于启动 FastAPI(或者其他基于 ASGI 的框架)应用程序。your_app:app:your_app是 Python 文件(不需要扩展名.py),其中包含 FastAPI 应用的代码。app是 Python 文件中的 FastAPI 实例。通常在 FastAPI 中,你会创建一个应用实例app = FastAPI(),这个实例就是这里提到的app。- 这部分是告诉
uvicorn需要运行哪个 Python 文件中的哪个 FastAPI 实例。
3. --reload
--reload是uvicorn的一个选项,用来开启自动重载功能。- 在开发阶段,开启
--reload后,当你修改了代码(例如,修改了 FastAPI 的路由或逻辑),uvicorn会自动检测到代码变化并重启应用程序,而无需手动停止和重新启动服务。 - 注意: 这个选项在生产环境中应该禁用,因为它会增加不必要的开销。
4. --host 0.0.0.0
--host用来指定服务器绑定的 IP 地址。0.0.0.0表示允许所有网络接口的访问,也就是说,服务器会监听所有 IP 地址的请求,通常用于让服务可以被外部访问。- 如果你只希望允许本地访问,可以将
host设置为127.0.0.1(localhost),这会将服务限制在本地计算机上。
5. --port 9000
--port用来指定服务器监听的端口号。9000表示你的应用将会监听 9000 端口,外界可以通过http://<服务器地址>:9000来访问你的 FastAPI 应用。- 你可以根据需要选择不同的端口号,但确保该端口没有被其他进程占用。
6. > uvicorn.log
>是输出重定向符号,用来将命令的标准输出(STDOUT)重定向到文件中。uvicorn.log是指定将标准输出内容写入到uvicorn.log文件中。这样,应用运行时的输出(如日志信息、调试信息等)会被保存到这个文件,而不会显示在终端中。
7. 2>&1
2>是错误输出重定向符号,它表示将标准错误输出(STDERR)重定向到指定的文件或目标。&1表示将标准错误输出(文件描述符 2)重定向到标准输出(文件描述符 1)的目标。2>&1的作用是将标准错误和标准输出合并并都重定向到同一个文件。在这个例子中,标准错误(例如程序的错误日志)和标准输出(正常的程序日志)都会被写入到uvicorn.log文件中。
8. &
&是一个后台运行符号,它将命令放入后台执行,并且让终端立即返回到命令行。- 如果没有
&,命令会在前台运行,终端会被阻塞,直到命令完成(例如应用程序终止)。 - 使用
&后,命令在后台运行,终端可以继续接受其他命令,而不需要等待后台进程完成。即使你关闭了终端,进程也会继续运行(但是这时仍然可能会因为终端关闭而中断,如果没有使用nohup)。
总结
nohup:确保进程在终端关闭后仍然继续运行。uvicorn your_app:app:启动 FastAPI 应用,your_app是包含应用的文件名,app是 FastAPI 实例。--reload:启用自动重载功能(通常用于开发阶段)。--host 0.0.0.0:允许外部访问,监听所有网络接口。--port 9000:设置应用监听的端口号。> uvicorn.log:将标准输出重定向到uvicorn.log文件。2>&1:将标准错误输出合并到标准输出,重定向到同一个日志文件。&:将命令放入后台运行。
因此,整体命令的作用是:在后台启动一个 FastAPI 应用,监听所有网络接口的 9000 端口,且输出和错误日志都写入 uvicorn.log 文件,并且即使关闭终端,进程依然会继续运行。
3、问题3
为什么这两个要连着一起写?2>&1
1. 文件描述符(File Descriptors)
在 Unix/Linux 系统中,所有的输入输出都通过文件描述符来进行管理。标准的输入输出有三个主要的文件描述符:
- 标准输入(STDIN):文件描述符 0,用于输入(通常是键盘输入)。
- 标准输出(STDOUT):文件描述符 1,用于正常输出(通常是显示在终端屏幕上的信息)。
- 标准错误输出(STDERR):文件描述符 2,用于输出错误信息(通常也是显示在终端屏幕上)。
2. > 和 2> 的作用
-
>:是重定向符号,表示将输出重定向到一个文件或其他地方。默认情况下,>会重定向标准输出(STDOUT)。例如,
echo "Hello" > output.txt会将"Hello"输出到output.txt文件中,而不是显示在终端。 -
2>:用于重定向 标准错误输出(STDERR)。2是文件描述符 2,表示标准错误。比如,echo "Error" > error.txt会将"Error"输出到error.txt文件中。如果你没有使用2>,则错误信息默认会显示在终端。
3. 2>&1 的含义
2>&1 的意思是将 标准错误输出(2) 重定向到 标准输出(1) 的地方。
2>表示你要重定向标准错误。&1代表将重定向的目标设置为 标准输出(文件描述符 1)。
所以,2>&1 就是告诉系统:“将标准错误输出(2)发送到标准输出(1)所指向的位置。”
4. 为什么要连着一起写?
它们必须连在一起写的原因是:
>本身是一个操作符,用来表示重定向。而&1是告诉系统去指向文件描述符 1(标准输出)。如果没有&,就会发生语法错误。2>表示重定向错误输出到某个目标,而&1告诉它目标是标准输出。系统首先会解析2>然后将它指向&1这个目标。
5. 举个例子:
假设你有一个命令,它同时输出正常的信息和错误信息:

浙公网安备 33010602011771号