我正在尝试在 bash 脚本中运行类似于以下命令的命令。它应该搜索所有子文件夹$sourcedir并将特定类型的所有文件复制到$targetdir.
#!/bin/bash
# These are set as arguments to the script, not hard-coded
sourcedir="/path/to/sourcedir"
targetdir="/path/to/targetdir"
find "$sourcedir" -type f -name "*.type" -exec sh -c 'cp "$1" "$2/`basename "$1"`"' "{}" "$targetdir" \;
Run Code Online (Sandbox Code Playgroud)
这似乎非常接近,除了{}没有被传递$2到-exec sh -c ...
我想尽可能接近“正确的方式”,并容忍文件名中的特殊字符(特别是单引号字符)。
编辑:我看到有人建议使用xargs或参数链接。我的印象是这仅适用于有限数量的参数。例如,如果我有数以千计的 .jpg 文件,我试图从多个画廊目录复制到一个巨大的幻灯片目录中,那么链接参数的解决方案是否仍然有效?
编辑 2:我的问题是我_在-exec命令中的第一个选项 sh 之前缺少一个。对于任何对如何使 find 命令工作感到好奇的人,添加_,一切都会好起来的:
find "$sourcedir" -type f -name "*.type" -exec sh -c 'cp "$1" "$2"' _ "{}" …Run Code Online (Sandbox Code Playgroud) umask如果激活 ACL,有人可以向我解释如何影响新创建文件的默认掩码吗?是否有一些关于此的文档?
例子:
$ mkdir test_dir && cd test_dir
$ setfacl -m d:someuser:rwx -m u:someuser:rwx . # give access to some user
$ getfacl .
# file: .
# owner: myUsername
# group: myGroup
user::rwx
user:someuser:rwx
group::---
mask::rwx
other::---
default:user::rwx
default:user:someuser:rwx
default:group::---
default:mask::rwx
default:other::---
$ umask # show my umask
077
$ echo "main(){}" > x.c # minimal C program
$ make x # build it
cc x.c -o x
$ getfacl x
# file: x
# owner: myUsername …Run Code Online (Sandbox Code Playgroud) 有这两个名称:subshell和child-shell。
是的,子进程将通过以下任一方式启动:
sh -c 'echo "Hello"'
( echo "hello" )
echo "$(echo "hello")
echo "hello" | cat
Run Code Online (Sandbox Code Playgroud)
是否全部相同并共享相同的名称?所有共享相同的属性吗?
POSIX有这个定义:
一个shell执行环境包括....
但是上面链接的最后一段是这样的:
子shell 环境应创建为shell 环境的副本,除了未被忽略的信号陷阱应设置为默认操作。
特别是:
命令替换、用括号分组的命令和异步列表应在子 shell 环境中执行。另外,多命令管道的每个命令都在一个子shell环境中;....
在sh -c 'echo "Hello"'不包括有,应该是可以称为子shell?
在 dash 中,函数和变量似乎位于不同的命名空间中:
fn(){
fn="hello world"
}
fn; echo "The value is $fn!" #prints: The value is hello world!
fn; echo "The value is $fn!" #prints: The value is hello world!
#the fn variable doesn't conflict with the fn function
Run Code Online (Sandbox Code Playgroud)
这是特定于破折号的功能还是 POSIX 保证?
我给了一个问题的答案,并评论它,让我阅读的基本定义的POSIX一致性部分弄清楚是否/dev/stdin,/dev/stdout而/dev/stderr实际上需要符合POSIX标准。
事实证明他们不是:
系统可能提供非标准扩展。这些是 POSIX.1-2008 不需要的功能,可能包括但不限于: [...] 具有特殊属性的附加字符特殊文件(例如
/dev/stdin,/dev/stdout、 和/dev/stderr)
据我所知,这是标准中唯一提到这些文件的地方。
我只能访问一个没有实现它们的“系统”(环境,真的),那就是 Windows 上的 MinGW(/dev就我所见,根本没有)。据我所知,所有免费的 Unices 都有,Cygwin、Windows 的新 Linux 环境和 Darwin/macOS 也有。
不过,我对商业 Unices 并不熟悉。
是否有一个 POSIX 系统、Unix 或某种描述的类 Unix 环境,今天还活着,它没有实现/dev/stdin, /dev/stdout, 和/dev/stderr作为文件系统中的文件?
POSIX sed documentation said:
A function can be preceded by one or more '!' characters, in which case the function shall be applied if the addresses do not select the pattern space. Zero or more <blank> characters shall be accepted before the first '!' character. It is unspecified whether <blank> characters can follow a '!' character, and conforming applications shall not follow a '!' character with <blank> characters.
So, with any POSIX sed, we can:
sed -e '/pattern/!d' file
Run Code Online (Sandbox Code Playgroud)
It's …
我正在查看具有以下内容的脚本:
if [ "${PS1-}" ]; then
Run Code Online (Sandbox Code Playgroud)
尾随的-错误让我有点,因为它似乎不是 Posix 或 Bash 标准语法。这是一些永远存在的神秘语法,还是打字错误?任何对标准/文档的引用将不胜感激。
通常我会编码它:
if [ "$PS1" ]; then
Run Code Online (Sandbox Code Playgroud)
哪个更正确或者它们之间有什么区别?
以与多个实现一起使用的 posix 兼容方式,如何打印当前定义的环境变量列表而没有它们的值?
在某些实现(mksh、freebsd /bin/sh)上,仅使用export本身就符合要求:
$ export
FOO2
FOO
Run Code Online (Sandbox Code Playgroud)
但是对于其他一些实现(bash、zsh、dash),export也会显示该值。以 bash 为例:
$ export
export FOO2='as df\
asdk=fja:\
asd=fa\
asdf'
export FOO='sjfkasjfd kjasdf:\
asdkj=fkajdsf:\
:askjfkajsf=asdfkj:\
safdkj'
$ printenv | sed -n l
FOO2=as\tdf\$
asdk=fja:\$
asd=fa\$
asdf$
FOO=sjfkasjfd kjasdf:\$
asdkj=fkajdsf:\$
\t:askjfkajsf=asdfkj:\$
safdkj$
Run Code Online (Sandbox Code Playgroud)
其他选项如env或printenv没有选项只打印没有值的变量名,至少在我尝试过的 linux 和 freebsd 平台上没有。
管道到 awk/sed/等。或者使用参数扩展技术(例如,${foo%%=*})修剪列表是可以接受的,但它必须处理可能跨越行并且值中包含=空格的值(参见上面的示例)。
特定于特定 shell 实现的答案很有趣,但我主要是在寻找跨实现兼容的东西。
GNUsed联机帮助页说:
该
-E选项切换为使用扩展正则表达式;
GNU sed 多年来一直支持它,现在已包含在 POSIX 中。
但是,POSIX Issue 7 (2018)sed并未-E作为选项列出。
哪里可以查看 POSIX 标准草案?
众所周知的是,UNIX的cron运行作业时,无论是日常的月或日的一周的比赛,如果两者都具有明确的价值,而不是一个星号通配符规定:
0 0 * * 1 # every Monday
0 0 1 * * # every month's first day
0 0 1 * 1 # every Monday *and also* every month's first day
0 0 1 * 1-7 # every day
0 0 1-31 * 1 # every day
Run Code Online (Sandbox Code Playgroud)
请注意这些常见示例*在月份字段中的所有内容。
POSIX 规范实际上是这样说的crontab(强调我的):
可以通过两个字段(月中的某天和一周中的某天)指定天数。如果月、月日、星期几都是<星号>字符,则匹配每一天。如果将月份或月份中的某一天指定为元素或列表,但星期几为 <星号>,则月份和月份中的日期字段应指定匹配的日期。如果月份和月份中的某天都指定为 <asterisk>,但星期几是元素或列表,则只有指定的星期几匹配。最后,如果将月份或月份中的某一天指定为元素或列表,并且将星期几也指定为元素或列表,则与月份和月份中的某一天或星期几匹配的任何一天,应匹配。
这似乎宣布了下述时间表将匹配任何一个月或一天的一周:
0 …Run Code Online (Sandbox Code Playgroud)