织梦CMS - 轻松建站从此开始!

欧博ABG官网-欧博官方网址-会员登入

" (double dash / double hyphen) mean?

时间:2025-09-21 15:17来源: 作者:admin 点击: 15 次
In commands that use the POSIX getopt() API to parse options, as well as several others, -- marks the end of options. In: rm -f -- -f The first -f is

In commands that use the POSIX getopt() API to parse options, as well as several others, -- marks the end of options.

In:

rm -f -- -f

The first -f is taken as an option to rm, while the second is taken as the name of a file to remove as everything past -- is not taken as an option.

In POSIX-compliant utilities and getopt() implementations, options are not accepted after non-option arguments, so for instance:

grep pattern -f

is required to look for lines matching pattern in the file called -f.

However, the GNU implementation of getopt() and its getopt_long() extension as used by most GNU utilities including GNU grep (but not bash nor any of its builtins even though bash is the GNU shell) doesn't do that by default unless there's a POSIXLY_CORRECT variable in the environment.

So, for those, -- is needed even if there are leading non-option arguments:

grep -- pattern -f

An older way to mark end of options was with -. You'll find that most sh implementations still support - as an end-of-option marker, as well as most of the builtins of ksh or zsh. That is however not common these days.

Some commands are known not to support -- as the end of option marker. Most echo implementations are among those. That's one of the reasons they can't be used to output arbitrary data.

⚠️ Important

That -- is needed when non-option arguments start with - (or possibly + for some commands), but also when you can't guarantee some non-option arguments won't start with -/+. That includes:

rm -f -- "$file"

rm -f -- "${files[@]}"

rm -f -- *.txt

rm -f -- $(command-that-generates-a-list-of-files-or-file-patterns)

cmd | xargs rm -f --

If you can't guarantee the command supports -- as the end of option marker, for those arguments that are file names, another approach is to prefix the file name with ./:

somegrep pattern ./*.txt

Failing to add those -- can introduce arbitrary command injection vulerabilities, especially if you also forget to quote your expansions. For instance:

sed -e 's/foo/bar/' *.txt

Will run reboot if there's a file called '-es/.*/reboot/e;#.txt' in the current working directory. Fixed by changing it to sed -e 's/foo/bar/' -- *.txt or sed -e 's/foo/bar/' ./*.txt.

Same for:

rename 's/foo/bar/' *foo*

with some rename variants; beware some (non-vulnerable) rename variants don't support --.

print $var

In zsh (even though leaving parameter expansions unquoted is relatively safe in that shell), will run reboot if $var contains -va[1$(reboot)]. Fixed with print -- $var or print - $var though you likely want print -r -- $var to also disable the backslash processing.

(责任编辑:)
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 验证码:
发布者资料
查看详细资料 发送留言 加为好友 用户等级: 注册时间:2025-10-05 12:10 最后登录:2025-10-05 12:10
栏目列表
推荐内容