linux shell: 命令运行符号(control operator) terminated ‘&‘的意义塈了解control operator指南

本文解析了在Bash脚本中使用‘&’符号使命令后台运行的技巧,介绍了其作为控制运算符的功能,以及如何在子shell中异步执行命令。文章引用了《Bash Reference Manual》中的权威解释。

好久以前就看到一些脚本中执行一个命令用’&'结尾,类似如下:

#!/bin/bash
lcd_test &

当时搞明白了意思,但现在又忘记了,赶紧补习一下在此做个记录:
根据stackoverflow上这个帖子《What does “&” at the end of a linux command mean?》的回答(如下图红框标),命令以’&'结尾就是让命令以后台形式运行

在这里插入图片描述

说实话,要照answer所说执行man bash来找到这个手册上的说明真不容易,我没找到,不过我在gnu的官网的
bash参考手册中找到了官方说明:《Bash Reference Manual》
《3.2.5 Coprocesses》节(如下图),可知‘&’是一个 control operator,与coproc等价,用于在subshell中异步执行命令。

在这里插入图片描述

并在 《3.7.3 Command Execution Environment》 找到关于‘&’ 更进一步的说明,如下图红框标注
在这里插入图片描述

关于什么是control operator,参见2 Definitions(如下图),我们所熟知的||,&&都是control operator
在这里插入图片描述

《Bash Reference Manual》是关于Bash很权威详尽的资料了,如果关于bash有什么不明白的,在这个文档中搜索到的都是最终答案。

<think>根据用户的问题,用户希望重载C++的流输出运算符`operator<<`以支持自定义类型`LayerSnapshot`的输出。这是一个关于运算符重载的常见需求,特别是在需要自定义输出格式时。 参考引用内容: - 引用[1]展示了在结构体中同时重载`operator<`和`operator<<`,其中`operator<<`被重载为友元函数。 - 引用[3]提到,`operator<<`通常不能重载为成员函数,而应该重载为非成员函数(通常是友元函数),因为它的左操作数是`ostream`对象,右操作数才是自定义类的对象。 因此,重载`operator<<`的常见做法是将其声明为类的友元函数,这样它就可以访问类的私有成员,同时又能以非成员函数的形式出现。 步骤: 1. 在`LayerSnapshot`类中声明`operator<<`为友元函数。 2. 在类外部定义这个函数,实现输出逻辑。 假设`LayerSnapshot`类有一些成员变量,比如`int id`和`std::string name`,那么重载`operator<<`的代码可能如下: ```cpp #include <iostream> #include <string> class LayerSnapshot { private: int id; std::string name; public: LayerSnapshot(int id, const std::string& name) : id(id), name(name) {} // 友元声明:重载operator<< friend std::ostream& operator<<(std::ostream& os, const LayerSnapshot& snapshot); }; // 定义operator<< std::ostream& operator<<(std::ostream& os, const LayerSnapshot& snapshot) { os << "LayerSnapshot(id=" << snapshot.id << ", name=" << snapshot.name << ")"; return os; } ``` 这样,当我们需要输出一个`LayerSnapshot`对象时,就可以像使用内置类型一样使用`<<`运算符: ```cpp int main() { LayerSnapshot snapshot(1, "Background"); std::cout << snapshot << std::endl; return 0; } ``` 输出结果将会是: ``` LayerSnapshot(id=1, name=Background) ``` 注意事项: 1. 重载函数必须返回`std::ostream&`的引用,以便支持链式输出(如`std::cout << a << b;`)。 2. 第一个参数是`std::ostream&`(输出流),第二个参数是自定义类的常量引用(避免复制)。 3. 由于需要访问私有成员,所以必须在类内声明为`friend`(友元)。 如果用户有更多的成员变量需要输出,只需在`operator<<`函数体中添加相应的输出语句即可。 §§相关问题§§ 1. 为什么重载输出运算符时通常要声明为友元函数? 2. 除了友元函数,还有其他方式重载输出运算符吗? 3. 在重载输出运算符时如何处理私有成员数据的输出?</think>### 重载`operator<<`以支持`LayerSnapshot`对象输出 在C++中,重载输出运算符`operator<<`需要遵循特定规则。以下是实现步骤和完整代码示例: #### 实现步骤 1. **声明为友元函数** 由于输出流对象`ostream`是左操作数(即`std::cout << obj`),无法作为成员函数的隐式参数,必须声明为友元函数。 2. **函数签名规范** ```cpp friend std::ostream& operator<<(std::ostream& os, const LayerSnapshot& obj); ``` 3. **访问私有成员** 友元声明使函数能访问类的私有成员变量。 4. **返回输出流引用** 必须返回`os`引用以支持链式调用(如`std::cout << obj1 << obj2`)。 #### 完整代码示例 ```cpp #include <iostream> #include <string> class LayerSnapshot { private: int layerId; std::string state; float opacity; public: LayerSnapshot(int id, std::string s, float op) : layerId(id), state(std::move(s)), opacity(op) {} // 声明友元运算符重载 friend std::ostream& operator<<(std::ostream& os, const LayerSnapshot& snapshot); }; // 实现运算符重载 std::ostream& operator<<(std::ostream& os, const LayerSnapshot& snapshot) { os << "LayerSnapshot {\n" << " ID: " << snapshot.layerId << "\n" << " State: " << snapshot.state << "\n" << " Opacity: " << snapshot.opacity << "%\n" << "}"; return os; // 返回流引用以支持链式调用 } int main() { LayerSnapshot snapshot(101, "Active", 85.5f); std::cout << snapshot << std::endl; // 输出自定义格式 return 0; } ``` #### 输出结果 ``` LayerSnapshot { ID: 101 State: Active Opacity: 85.5% } ``` #### 关键注意事项 1. **必须为非成员函数** 若定义为成员函数,左操作数会变成`*this`,导致`std::cout << obj`变成`obj.operator<<(std::cout)`,语法错误[^3]。 2. **常量正确性** 第二个参数应为`const LayerSnapshot&`,避免意外修改对象。 3. **格式化自由** 在实现中可自定义输出格式(如添加缩进、标签等)。 4. **性能优化** - 使用`const&`避免拷贝 - 返回`ostream&`支持链式调用 - 移动语义处理字符串参数(如示例中的`std::move`) > 此实现遵循C++标准库的通用设计模式,与`std::vector`等类型的输出机制保持一致[^1][^3]。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

10km

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值