这个问题不是关于如何编写正确转义的字符串文字。我找不到任何与如何转义变量以在脚本或其他程序中直接使用的相关问题。
我的目标是使脚本能够生成其他脚本。这是因为生成的脚本中的任务将在另一台机器上运行 0 到n次,并且生成它们的数据在运行(再次)之前可能会发生变化,因此直接通过网络执行操作将不行。
给定一个可能包含特殊字符(例如单引号)的已知变量,我需要将其写为完全转义的字符串文字,例如,foo包含的变量bar'baz应出现在生成的脚本中:
qux='bar'\''baz'
Run Code Online (Sandbox Code Playgroud)
这将通过附加"qux=$foo_esc"到其他脚本行来编写。我是这样使用 Perl 做到的:
foo_esc="'`perl -pe 's/('\'')/\\1\\\\\\1\\1/g' <<<"$foo"`'"
Run Code Online (Sandbox Code Playgroud)
但这似乎有点矫枉过正。
我单独使用 bash 没有成功。我已经尝试了这些的许多变体:
foo_esc="'${file//\'/\'\\\'\'}'"
foo_esc="'${file//\'/'\\''}'"
Run Code Online (Sandbox Code Playgroud)
但是输出中会出现额外的斜杠(当我这样做时echo "$foo"),或者它们会导致语法错误(如果从 shell 完成,则需要进一步的输入)。
我在根目录中有 ubuntu 文件系统目录,我不小心将数百个文件复制到根目录中。
我直觉地试图通过排除文件系统来删除复制的文件
rm -rf !{bin,sbin,usr,opt,lib,var,etc,srv,libx32,lib64,run,boot,proc,sys,dev} ./.
Run Code Online (Sandbox Code Playgroud)
但它不起作用。在删除整个目录时排除某些目录的正确方法是什么?
编辑:永远不要在不知道该怎么做的情况下尝试这里的任何命令!
bash 文件名扩展(通配)是否有最大值,如果是,它是什么?见通配符的tldp.org。
假设我想对文件子集运行命令:
grep -e bar foo*
rm -f bar*
Run Code Online (Sandbox Code Playgroud)
bash 将扩展到多少个文件是否有限制,如果有,它是什么?
我不是在寻找执行这些操作的替代方法(例如,通过使用find)。
我正在尝试为 fail2ban jail 匹配文件名 - 所以我只需要使用文件名通配符 - 而不是正则表达式或 bash 脚本。
我的/var/log/apache2目录包含文件,包括:
example.com.error.log
db.example.com.error.log
app1.example.com.error.log
app2.example.com.error.log
Run Code Online (Sandbox Code Playgroud)
我正在尝试创建一个 glob 来匹配所有以.error.log except 结尾的文件db.example.error.log- 这可能吗?
我试过了,!(db)*.error.log但这仍然匹配db.example.com.error.log。我猜!()不匹配任何字符,允许*从文件名的开头匹配。
注意:我不想appX在添加新日志文件时扩展 glob ,所以我不能使用@()当前已知的非数据库文件名列表。
(背景:我想创建一个过滤器,禁止任何人在除db.example.com之外的任何域上请求任何 phpMyAdmin URL )
取消引用中的变量时bash,必须使用$符号。尽管如此,以下似乎工作得很好:
x=5
[[ x -gt 2 ]]
Run Code Online (Sandbox Code Playgroud)
有人可以解释一下吗?
编辑:(更多信息)
我的意思是 [[ ]] 命令如何以及为什么取消引用我的变量 x 没有 $ 符号。是的,如果 x=1,则该语句被评估为 false(返回状态 1)
我发现自己<command> --help | grep <feature>每天都在做非常非常频繁的事情。我想知道是否有可能使类似的东西^^扩展到"--help | grep"然后我这样做:
ls ^^ size
Run Code Online (Sandbox Code Playgroud)
这将执行以下操作:
ls --help | grep size
Run Code Online (Sandbox Code Playgroud) or例如,在读取文件时是否可以在 shell 中扩展选项。
我的意思是,例如,grep支持(A|B)在文件中匹配 A 或 B 之类的语法。
同样,如果我有这些文件:
file1.txt
file2.txt
file3.txt
file4.txt
file5.txt
Run Code Online (Sandbox Code Playgroud)
我能做到cat file{1..5}.txt的bash,因为它扩大了范围。是否有一种等效的方法可以仅对几个文件执行此操作?
例如cat file(1|5).txt,只打印那些 2?
我正在尝试将剪贴板内容保存到 sqlite 数据库中。创建数据库和表。
我不希望它journal在每次剪贴板更改时都创建文件,所以我尝试传递PRAGMA journal_mode = OFF;标志。但是在单行命令中传递这些命令很棘手,因为sqlite只接受两个命令,例如
sqlite3 clipboard_archive.db "insert into cb (cb_context) values ('clipboard');"
Run Code Online (Sandbox Code Playgroud)
有用。我寻找Q&A网站,一些建议以下列方式回显命令。
echo "PRAGMA journal_mode = OFF;" | sqlite3 clipboard_archive.db "insert into cb (cb_context) values ('clipboard');"
Run Code Online (Sandbox Code Playgroud)
但是PRAGMA journal_mode = OFF;虽然它在sqlite3命令提示符下工作,但不会以这种方式生效。
我的一个班轮脚本有什么问题?
我想为每个月创建一个目录名称。我知道,在玩了一些 shell 之后,:
date -d 1/01 +%b # Gives Jan
date -d 2/01 +%b # Gives Feb
.
date -d 12/01 +%b # Gives Dec
Run Code Online (Sandbox Code Playgroud)
所以我使用了大括号扩展,echo {1..12}/01并尝试了xargs它:
echo {1..12}/01 | xargs -n 1 -I {} date -d {} +%b
Run Code Online (Sandbox Code Playgroud)
但它失败了:/(之后我想申请mkdir)。我怎样才能做到这一点?
我在一个目录中,其中有两个文本文件:
$ touch test1.txt
$ touch test2.txt
Run Code Online (Sandbox Code Playgroud)
当我尝试使用某种模式列出文件(使用 Bash)时,它可以工作:
$ ls test?.txt
test1.txt test2.txt
$ ls test{1,2}.txt
test1.txt test2.txt
Run Code Online (Sandbox Code Playgroud)
然而,当一个模式由包含在 中的命令产生时$(),只有一种模式有效:
$ ls $(echo 'test?.txt')
test1.txt test2.txt
$ ls $(echo 'test{1,2}.txt')
ls: cannot access test{1,2}.txt: No such file or directory
Run Code Online (Sandbox Code Playgroud)
这里发生了什么?为什么模式{1,2}不起作用?
bash-expansion ×10
bash ×9
wildcards ×3
shell-script ×2
filenames ×1
rm ×1
shell ×1
sqlite ×1
variable ×1
xargs ×1