小编tox*_*lot的帖子

何时编写可移植脚本很重要?

我编写的大多数代码都是用 PHP 编写的。我最近开始学习 shell 脚本。我遇到的大多数资源和教程都是针对 Bash 的。有些人对 bashisms 提出警告,有些人则没有。我在这里和 Stack Overflow 上读了很多。

每当答案使用bashisms 时总会有人评论说:

你不应该使用 <insert bashism here>。它不便携。

即使问题被标记为 ,也会发生这种情况bash。对我来说,这就像告诉 PHP 程序员他们不应该使用 PHP 5 中的新代码,因为它不能与 PHP 4 一起使用。或者告诉某人他们不应该为 Mac 编写一些东西,因为它不能使用在 Windows 上。

当我用 PHP 编写时,我会选择一个最低要求并编写向前兼容的代码。我不担心让它向后兼容。

如果我#!/bin/bash用作shebang,为什么不应该使用bashisms?我开始觉得有些人只是为了它而喜欢抨击bashisms(双关语)。

人们经常使用bashshell互换——可能是因为 bash 是许多系统上的默认 shell。所以我可以理解添加注释来警告代码使用 bashisms,但我不明白使用它们是错误的含义。

显然,如果我编写的脚本严格供个人使用,我可以用我想要的任何语言编写它。但我想我写的一些代码可能对其他人有用。

在发布之前,我尝试搜索我的问题的答案。我找到了很多关于如何测试可移植性的信息,但找不到任何关于何时这样做很重要的信息

那么,何时编写可移植脚本很重要?

例如,

  • 什么类型的脚本应该尽可能可移植?
  • 没有安装 Bash 的系统有多常见?
  • 如果系统安装了 Bash,它还会有 GNU …

shell scripting bash portability

18
推荐指数
2
解决办法
1369
查看次数

如何查找文件名中包含换行符的文件?

我正在尝试查找文件名中有换行符的文件。但我不知道使用什么模式。

以下有效,但如果我想在缩进代码中使用它,则不是很有用。

find . -name '*
*'
Run Code Online (Sandbox Code Playgroud)

我尝试了这两个,他们只成功找到了包含字母n 的文件名:

find . -name '*\n*'
find . -name "*\n*"
Run Code Online (Sandbox Code Playgroud)

然后我找到了如何编写反斜杠转义序列并尝试了这个:

find . -name "*$'\n'*"
Run Code Online (Sandbox Code Playgroud)

但这并没有找到任何东西。我应该如何写模式?

shell find patterns

11
推荐指数
1
解决办法
4149
查看次数

$0 是否总是包含脚本的路径?

我想 grep 当前脚本,以便我可以从顶部的评论部分打印帮助和版本信息。

我在想这样的事情:

grep '^#h ' -- "$0" | sed -e 's/#h //'
Run Code Online (Sandbox Code Playgroud)

但是后来我想知道如果脚本位于 PATH 中的目录中并且在没有明确指定目录的情况下调用会发生什么。

我搜索了特殊变量的解释,并找到了以下描述$0

  • 当前 shell 或程序的名称

  • 当前脚本的文件名

  • 脚本本身的名称

  • 运行时的命令

$0如果在没有目录的情况下调用脚本,这些都没有说明 的值是否包含目录。最后一个实际上向我暗示它不会。

在我的系统上测试(Bash 4.1)

我在 /usr/local/bin中用一行创建了一个名为scriptname的可执行文件,echo $0并从不同的位置调用它。

这些是我的结果:

> cd /usr/local/bin/test
> ../scriptname
../scriptname

> cd /usr/local/bin
> ./scriptname
./scriptname

> cd /usr/local
> bin/scriptname
bin/scriptname

> cd /tmp
> /usr/local/bin/scriptname
/usr/local/bin/scriptname

> scriptname
/usr/local/bin/scriptname
Run Code Online (Sandbox Code Playgroud)

在这些测试中, 的值$0始终与脚本的调用方式完全相同,除非它是在没有任何路径组件的情况下调用的。在这种情况下, 的值$0绝对路径。所以看起来传递给另一个命令是安全的。

但是后来我在Stack …

path shell-script

11
推荐指数
2
解决办法
2万
查看次数

如果子目录的执行权限被拒绝,“find -depth”的预期行为?

我想知道我是否可以依赖使用findwith-depth选项时看到的行为,并且用户没有子目录的执行权限。

假设以下目录结构:

drwxrwxrwt. 10 root    root     12288 Mar 14 04:31 .
dr-xr-xr-x. 24 root    root      4096 Dec  6 03:33 ..
drwx------   4 root    root      4096 Mar 14 04:03 jen
Run Code Online (Sandbox Code Playgroud)

以非 root 用户身份运行以下命令:

find -type d
Run Code Online (Sandbox Code Playgroud)

输出是:

.
./jen
find: `./jen': Permission denied
Run Code Online (Sandbox Code Playgroud)

所以find找到目录jen并输出。然后它试图下降到jen,但没有许可,所以它打印了错误。上面的第一行打印到stdout,第二行打印到stderr

现在以非 root 用户身份运行以下命令:

find -depth -type d
Run Code Online (Sandbox Code Playgroud)

输出是:

find: `./jen': Permission denied
.
Run Code Online (Sandbox Code Playgroud)

因此,stdout除非用户具有列出目录内容的权限,否则不会输出路径名。

这个输出非常适合我想做的事情。但是,我不确定这是否只是巧合。我可以依赖这种行为吗?

我正在使用 GNU findutils 4.4.2。我想知道所有版本的find …

permissions directory find

7
推荐指数
1
解决办法
3462
查看次数