我正在使用以下两个命令创建一个0B文件并将其扩展名设置为644
touch filename.ext
chmod 777 filename.txt
我想问的是在Unix(Korn Shell)中是否有任何单个命令可以一次性完成两件事情,即创建一个具有所需权限的0B文件?
我正在使用以下两个命令创建一个0B文件并将其扩展名设置为644
touch filename.ext
chmod 777 filename.txt
我想问的是在Unix(Korn Shell)中是否有任何单个命令可以一次性完成两件事情,即创建一个具有所需权限的0B文件?
install -m 777 /dev/null filename.txt
install -m 700 -d /tmp/mydir
。 - Fernando Fabretiinstall /dev/null script.sh
很好用,因为 install
的默认权限是 755
。 - CJ Dennismkdir
:mkdir -m 700 /tmp/mydir
。 - Cromax-m
代表 --mode=MODE
。 -o, --owner=OWNER
和 -g, --group=GROUP
选项也很有用。 - Константин Ван首先,您绝不能将任何内容设置为777
权限。这是一个巨大的安全问题,也没有必要这么做。对于此问题,我将假设您希望创建的文件权限比默认值更安全,例如600
。
使用大多数bash工具来安全地创建和更改文件权限并没有一种通用的方法。即使在Paul的答案中使用了棘手的重定向技巧,实际上也会短暂地创建一个具有默认权限的文件,然后重置它们。除非创建程序在节点创建时向操作系统发送非常特定的请求,否则所有新文件都将根据系统umask值创建。 133
的掩码很常见,这意味着您的文件将从一开始就以644
权限创建。
除了使用chmod
命令在创建文件后设置文件权限外,您还可以使用umask
命令告诉系统您想要的默认值。
$ umask 077
$ touch test_file
$ ls -l test_file
-rw------- 1 user group 0 Jan 24 22:43 test_file
请注意,该文件已使用600
权限创建。
在您关闭shell或手动设置其他值之前,此权限将对在shell中运行的所有命令生效。如果您想要使用此结构来运行单个命令(甚至是一小组命令),将命令隔离在子shell中可能会很有用。
$ (umask 077 ; touch test_file)
请注意,您将括号中的任何其他内容都将使用该umask,但一旦关闭它,您就会回到先前的环境。+x
)权限,并确保告诉 Web 服务器里面的任何内容都不应该运行(例如,PHP 文件只能作为原始内容下载,而不能作为代码“运行”)。 - Caleb对于bash,只需要使用文件重定向和历史扩展的chmod
命令:
chmod 777 filename.txt>>!#:2
对于ksh
和zsh
,您必须放弃历史扩展(如上所示,可能还有其他方法)并使用:
chmod 644 filename>>filename
对于任何你没有(而且真的不需要)历史扩展功能的shell脚本,也请使用上述方法。
!#:2
部分吗? - midnite!#:2
是一个历史命令:!
标记历史命令的开始;#
指代 这个 命令;:2
指代这个命令的第二个参数(即 filename.txt
)。 - Paul Evans>>
可以“工作”,但那只是在文件不存在时。如果它已经存在并且有内容,你将会得到错误的内容(OP 想要“一个 0B 文件”)。>
才是正确的版本。此外,重定向 chmod
的输出真的没有意义。这会让人觉得有输出需要重定向,但实际上并没有。这种方法还依赖于 shell 的微妙行为(首先创建输出重定向文件,然后运行 chmod
),并且仍然遭受相同的问题(在两个非原子步骤中创建文件,然后更改权限)。 - Ken Williamsinstall
来进行进程替换:
如果您想要创建的文件不仅为空,而且具有内容和模式,您可以在bash中使用install
来进行进程替换:
install -m 755 <(echo commands go here) newscript
<()
将输出放入临时文件中 (进程替换)
create () {
touch "$1"
chmod "$2" "$1"
}
create filename.ext 644
umask
。如果你禁用了umask
:umask 0
当你触碰文件时,它会自动以权限666结束。通常情况下,将文本文件设置为可执行并不是一个好主意。禁用umask
后,目录将以777权限结束。
chicks@freecandy /tmp $ umask
0022
chicks@freecandy /tmp $ touch x
chicks@freecandy /tmp $ mkdir xx
chicks@freecandy /tmp $ umask 0
chicks@freecandy /tmp $ touch y
chicks@freecandy /tmp $ mkdir yy
chicks@freecandy /tmp $ ls -ld x xx y yy
-rw-r--r-- 1 chicks chicks 484 Jan 24 14:37 x
drwxr-xr-x 2 chicks chicks 4096 Jan 24 14:37 xx
-rw-rw-rw- 1 chicks chicks 0 Jan 24 14:37 y
drwxrwxrwx 2 chicks chicks 4096 Jan 24 14:37 yy
umask
更改回其先前的值? - SherylHohmantouch filename.ext && chmod 777 $_
$_是最近的参数。
但正如其他人所说,777不是一个好主意。
由于Docker和Alpine的存在,我想有很多人对创建可执行的单行命令感兴趣,而不需要bash-isms的帮助。使用install
非常简单。
$ docker build -t temp - <<EOF
FROM alpine
RUN echo "date" | install -m 775 /dev/stdin /bin/now
CMD /bin/now
EOF
Sending build context to Docker daemon 2.048kB
Step 1/3 : FROM alpine
---> d6e46aa2470d
Step 2/3 : RUN echo "date" | install -m 775 /dev/stdin /bin/now
---> Running in 95919b575638
Removing intermediate container 95919b575638
---> cd1fafd96ef3
Step 3/3 : CMD /bin/now
---> Running in 03b5c3ac7265
Removing intermediate container 03b5c3ac7265
---> 8f30b527dd29
Successfully built 8f30b527dd29
Successfully tagged temp:latest
$ docker run --rm temp
Thu Nov 12 07:44:24 UTC 2020
$ docker run --rm temp ls -la /bin/now
-rwxrwxr-x 1 root root 5 Nov 12 07:44 /bin/now
$ docker rmi temp
Untagged: temp:latest
Deleted: sha256:8f30b527dd29203b67c86290b34b0a29d3c98a48134609d0b1e2b89087a7d6e7
Deleted: sha256:cd1fafd96ef3084226c5f98f472e3e08bc9a9f0448cc3e68b6f1c192d12d778a
Deleted: sha256:e58c75acbf953a64d35089cf50e1c5b762601e1cb9d9d1d668e135f23ce1fe86
一位评论者说:
我不明白这与问题有什么关系。
这个主题会出现在Docker用户的Google搜索中。 OP指定了“korn shell”,这意味着要避免bash特定的功能。因为Alpine和许多其他用于容器的最小Linux基础不包括bash,所以排名靠前的答案对他们不起作用。我的答案适用于他们和OP的korn shell。使用Docker演示解决方案意味着任何使用Linux、macOS、Windows或WSL2 in Windows的人都可以通过阅读来自我的机器的转录轻松地在他们的机器上重新创建演示。
stdin
中传输的内容的文件。此答案的其他部分仅演示该技术的工作原理,因此也很有用,尽管我认为它可以更清晰地表述。 - Ken Williamsinstall
不能保证能够处理设备文件。这太糟糕了,因为它本来是我使用场景的完美解决方案(从echo
中传输内容)。 - Ken Williams/dev/null
是一个有效的来源,我仍然感到惊讶。我不再使用Mac,但我会看看是否能找到重现您的问题并找到解决方案的方法。感谢您的反馈。 - Bruno Bronoskyinstall
二进制文件和许多其他核心实用程序(例如grep
,date
,mktemp
等)已经从AT&T Unix版本重写为GNU / Linux,并且尽管尝试保留大多数标志的行为,但存在明显的差异。Unix被BSD采用,而在macOS下面的Darwin内核则采用了FreeBSD的原始Unix用户空间的后期版本。 - Ryder