小编Ale*_*lis的帖子

为什么反斜杠会阻止别名扩展?

在我的问题的第一部分,我将提供一些背景信息作为社区服务.第二部分包含实际问题.

第一部分

假设我创建了以下别名:

alias ls='ls -r'
Run Code Online (Sandbox Code Playgroud)

我知道如何使用以下方式暂时unalias(即覆盖此别名),使用:

1)命令的完整路径名: /bin/ls

2)命令替换: $(which ls)

3)内置命令: command ls

4)双引号: "ls"

5)单引号: 'ls'

6)反斜杠字符: \ls

案例1是显而易见的,案例2只是一种变化.案例3中内置的命令旨在忽略shell函数,但显然它也可用于规避别名.最后,案例4和5与POSIX标准(2.3.1)一致:

"应检查一个被识别为简单命令的命令名字的结果字,以确定它是否是一个不带引号的有效别名."

Bash参考手册(6.6):

"检查每个简单命令的第一个单词,如果没有引用,则检查它是否有别名."

第二部分

这是一个问题:为什么案例6(通过说法覆盖别名\ls)考虑引用这个词?为了与这个问题的风格保持一致,我正在寻找对"官方"文档的引用.

文档说反斜杠只转义后续字符,而不是单引号和双引号引用一系列字符. POSIX标准(2.2.1):

"未引用的反斜杠应保留以下字符的字面值,但<newline>除外"

Bash参考手册(3.1.2.1):

"一个非引用的反斜杠'\'是Bash转义字符.它保留了下一个字符的字面值,除了换行符."

(顺便说一句,是不是"下一个角色"有点矫枉过正?)

一个可能的答案可能是这种情况并不那么特别:它类似于ANSI-C引用中的一些情况,例如\nnn.然而,这仍然是逸出的单个字符(八位字符,其值是八进制值NNN),而不是一个字符序列.

bash shell alias posix escaping

23
推荐指数
2
解决办法
4428
查看次数

多余的位置参数,解包参数列表或元组,以及扩展的可迭代解包

这个问题会很长,所以我先发制人道歉.

在Python中,我们可以在以下三种情况下使用*:

I.在定义一个我们想要用任意数量的参数调用的函数时,例如在这个例子中:

def write_multiple_items(file, separator, *args):
    file.write(separator.join(args))
Run Code Online (Sandbox Code Playgroud)

在这种情况下,多余的位置参数被收集到元组中.

II.相反的情况是,当参数已经在列表元组中时,我们希望为需要单独位置参数的函数调用解包它们,例如在本例中:

>>> range(3, 6)             # normal call with separate arguments
[3, 4, 5]
>>> args = [3, 6]
>>> range(*args)            # call with arguments unpacked from a list
[3, 4, 5]
Run Code Online (Sandbox Code Playgroud)

III.从Python 3开始,*也用于扩展列表元组解包的上下文中,例如在这个示例中用于元组:

>>> a, *b, c = range(5)
>>> b
[1, 2, 3]
Run Code Online (Sandbox Code Playgroud)

或列表:

>>> [a, *b, c] = range(5)
>>> …
Run Code Online (Sandbox Code Playgroud)

python tuples list

5
推荐指数
2
解决办法
2045
查看次数

构造函数初始化列表:来自C++ Primer的代码,第16章

在"C++ Primer"的第16章末尾,我遇到了以下代码(我删除了一堆行):

class Sales_item {
public:
    // default constructor: unbound handle
    Sales_item(): h() { }
private:
    Handle<Item_base> h;   // use-counted handle
};
Run Code Online (Sandbox Code Playgroud)

我的问题在于Sales_item(): h() { }线路.

为了完整起见,我还要引用我认为与我的问题相关的Handle类模板的部分(我想我不需要显示Item_base类):

template <class T> class Handle {
public:
    // unbound handle
    Handle(T *p = 0): ptr(p), use(new size_t(1)) { }
private:
    T* ptr;          // shared object
    size_t *use;     // count of how many Handles point to *ptr
};
Run Code Online (Sandbox Code Playgroud)

我原以为是这样的:

a)Sales_item(): h(0) { }这是作者在前几章中反复使用的惯例,或者

b)Handle<Item_base>()如果打算调用Handle类的默认构造函数.

相反,这本书有什么Sales_item(): h() { …

c++ initialization-list

4
推荐指数
1
解决办法
397
查看次数

为什么const_cast需要说明你要投射的内容?

根据标准(§5.2.11),const_cast抛弃了cv-qualifiers(const或volatile).

这是一个简单的例子.首先,您声明两个函数采用指针和引用:

class Bar { ... };
void foo_ptr(Bar*);
void foo_ref(Bar&);
Run Code Online (Sandbox Code Playgroud)

然后你创建一个引用到const:

Bar b;
const Bar& cb = b;
Run Code Online (Sandbox Code Playgroud)

然后你可以使用适当的const_cast调用任一函数:

foo_ptr(const_cast<Bar*>(&cb));
foo_ref(const_cast<Bar&>(cb));
Run Code Online (Sandbox Code Playgroud)

这是我的问题:由于const_cast无法完成其他演员的设计,你投射的内容不是很明显吗?换句话说,为什么语言不允许我简单地说:

foo_ptr(const_cast<>(&cb));
foo_ref(const_cast<>(cb));
Run Code Online (Sandbox Code Playgroud)

我只能想到以下两个原因:

a)当我尝试做一些疯狂的事情时,编译器应该阻止我,例如:

foo_ptr(const_cast<int*>(&cb));
foo_ref(const_cast<int&>(cb));
Run Code Online (Sandbox Code Playgroud)

并强迫我明确说明我正在施放的类型,然后可以防止行为不端.我发现这个(假设的)解释很弱,因为如果语言偏好允许我写下错误只是为了让编译器纠正我,这将是奇怪的.

b)如果变量既是const又是volatile,则可能存在歧义.在这种情况下,编译器无法告诉我是否试图抛弃一个或另一个(或两者).

这是为什么,还是有其他原因?

c++ standards casting

4
推荐指数
1
解决办法
801
查看次数

exec n <&m vs exec n>&m - 基于Sobell的Linux书籍

在Mark Sobell的"Linux命令,编辑器和Shell编程实用指南"第二版中,他写道(第432页):

<&token复制输入文件描述符; >&复制输出文件描述符.

这似乎与同一页面上的另一个语句不一致:

使用以下格式打开或重定向文件描述符n作为文件描述符m的副本:

exec n <&m

并在同一页面上也有一个例子:

# File descriptor 3 duplicates standard input
# File descriptor 4 duplicates standard output
exec 3<&0 4<&1
Run Code Online (Sandbox Code Playgroud)

如果> &&重复输出文件描述符,那么我们不应该说

exec 4>&1
Run Code Online (Sandbox Code Playgroud)

复制标准输出?

unix linux bash shell file-descriptor

4
推荐指数
1
解决办法
2322
查看次数