我想将我在破折号脚本中设置的一些环境变量导出到一个文件中:
myvariable="line 1
LINE=3
some characters: # \" \$
line 5"
myvariable2="abc"
export myvariable myvariable2
Run Code Online (Sandbox Code Playgroud)
预期结果(可用脚本):
declare -x myvariable="line 1
LINE=3
some characters: # \" \$
line 5"
declare -x myvariable2="abc"
Run Code Online (Sandbox Code Playgroud)
结果就是我使用export命令得到的结果。但它导出所有 envvars 并且不允许过滤。由于变量的多行字符,grep结果是不可能的。
相比之下,该printenv命令只允许输出选择的变量,但它不关心转义,并且在此用例中不输出变量名称。
我决定要更多地了解 Linux 并尝试构建 LFS。我使用 Ubuntu 11.04 作为主机系统,Ubuntu 默认使用 dash 和 mawk。我已将 mawk 更改为 gawk,但考虑到 mawk 比 gawk 快得多,我想我可能还是想使用 mawk。
由于将 bash 设为默认 shell 会对系统性能产生负面影响,尤其是启动时间,我对进行更改犹豫不决。
在 LFS 书中,您可以阅读以下内容:
指向其他软件(例如 dash、mawk 等)的符号链接可能有效,但未经 LFS 开发团队测试或支持,并且可能需要偏离说明或对某些软件包附加补丁。
所以如果出现问题,我基本上是靠自己的,但它可能会奏效。所以我希望有更多经验的人可以告诉我它是否会起作用,如果不会,需要什么才能使它起作用?
只是想我会记录这个:我正在尝试一些非常简单的事情 - 在 中设置 env 变量bash,然后打印出来:
$ bash -c "a=1; echo a$a;"
a
$ bash -c "a=1; echo a\$a;"
a1
Run Code Online (Sandbox Code Playgroud)
现在我想要同样的东西,但作为参数调用sh(在我的系统上,ls -la $(which sh)给出/bin/sh -> dash):
$ sh -c "bash -c "a=1; echo a\$a;""
a$a
# obviously I have to escape inner quotes:
$ sh -c "bash -c \"a=1; echo a\$a;\""
a
# escape the dollar once more?
$ sh -c "bash -c \"a=1; echo a\\$a\" "
sh: Syntax error: Unterminated quoted …Run Code Online (Sandbox Code Playgroud) 当我登录到dash默认 shell 的服务器时,我收到如下提示:
\[\033[1;31m\]\u\[\033[0m\]@:\w #
Run Code Online (Sandbox Code Playgroud)
如何配置显示类似内容的服务器?
user@hostname!dash!/path/$
Run Code Online (Sandbox Code Playgroud)
以防万一,我必须把它放进去,我.profile怎么能把漂亮的外壳放在其他外壳里,比如bash和zsh?
(在我的服务器上.profile是一个符号链接.bashrc)
请参阅下面的代码:
a()(alias x=echo\ hi;type x;alias;x);a
Run Code Online (Sandbox Code Playgroud)
我在函数中有一个别名,我不想更改外部环境(这就是为什么我使用()而不是{}),即使代码说别名已成功设置,它也不起作用,请检查输出:
x is aliased to `echo hi'
...
alias x='echo hi'
x: command not found
Run Code Online (Sandbox Code Playgroud)
我听说这样做shopt -s expand_aliases可以解决,但不只是它没有任何效果,以及我不能依靠bash,因为我有工作dd-wrt的busybox的ash。
有人知道这个问题吗?
在本节trap中的破折号手册页出现如下提示:
不带任何参数的trap导致它以适合作为 shell 输入的格式将信号列表及其相关操作写入标准输出,以实现相同的捕获结果。
惊人的!我以为我找到了一种简单的方法来恢复我已经覆盖的以前的信号处理程序,方法是将trap的输出作为命令返回给 shell:
trap "echo 'good'" EXIT
# save signal handlers to $traps
traps="$(trap)"
# override EXIT handler
trap "echo 'bad'" EXIT
# reinstate original handlers
eval "$traps"
Run Code Online (Sandbox Code Playgroud)
期望的输出: good
实际输出: bad
这是完全合乎逻辑的,因为它$traps是空的,这又与联机帮助页一致:
当 shell 分叉出一个子 shell 时,它会将被捕获(但不会被忽略)的信号重置为默认操作。
(命令替换$(trap)分叉出一个子shell,所以trap不知道任何信号处理程序。)
一切似乎都按其应有的方式行事。但是如何利用trap的列表功能呢?
我试图导出 Python 环境要求,这就是我打算做的:
conda list -e > requirements.txt
Run Code Online (Sandbox Code Playgroud)
但是我错误地输入了这个:
conda list -e -> requirements.txt
Run Code Online (Sandbox Code Playgroud)
它仍然有效,但文件的内容行较少。我想知道究竟发生了什么。我搜索过,但-在这种情况下我找不到解释。
我有一个 shell 脚本,它使用单个变量作为关联数组(KEY=VALUE每行一个)。
在脚本的整个执行过程中,变量被操纵以添加、删除或修改条目:
附加:
VARIABLE="$(printf "%s\n%s" "$VARIABLE" "KEY=VALUE")"
Run Code Online (Sandbox Code Playgroud)
调整:
VARIABLE="$(printf "%s\n" "$VARIABLE" | sed -E "s,^(KEY=).*$,\1VALUE,")"
Run Code Online (Sandbox Code Playgroud)
消除:
VARIABLE="$(printf "%s\n" "$VARIABLE" | grep -E -v "^KEY=.*$")"
Run Code Online (Sandbox Code Playgroud)
在终端中执行时(或作为sysv下的旧机器上的服务通过 init 脚本),该脚本运行良好,但是当作为systemd下的服务运行时,一段时间后,脚本开始在日志 :
sh: printf: I/O error
经过大量的反复试验,我无法确定脚本中的哪些命令产生了这些错误,但我注意到当变量的长度达到 8000 字节时它们开始出现(我猜是 8192,但我由于附加了整行,因此无法准确指出它)。
我很确定变量长度是问题所在,因为我实现了一个例程,当变量长度接近 8192 字节时,它会修剪数组中最旧的条目,现在脚本确实运行systemd了很长时间而没有错误;但这当然不理想,因为会丢失一些信息。
我在网上搜索了有关 shell 脚本中最大可变长度的信息,但没有找到任何有用的信息:
dash 手册页没有说明最大可变长度。
对于那些想要编写可移植sed脚本的人,请注意某些实现已将行长度(对于模式和保持空间)限制为不超过 4000 字节。的POSIX标准规定符合sed的实施方式应支持至少8192米字节行的长度。GNU sed没有内置的行长限制;只要它可以malloc()更多(虚拟)内存,您就可以随心所欲地馈送或构造行。
...但这适用于行长,而不是整个文本长度(单行不超过 80 个字符)
无论如何,由于错误仅在脚本运行时出现 …
我只想等待用户通过按 确认消息Return。在 bash 中,我可以调用
$ read
$
Run Code Online (Sandbox Code Playgroud)
但是,在 sh (在我的情况下是破折号),我得到
$ read
sh: 1: read: arg count
$
Run Code Online (Sandbox Code Playgroud)
看来我必须提供一个论点?这种差异从何而来?
我正在使用dash作为/bin/sh. 在我的脚本中,我有以下几行:
SSH_AUTH_SOCK=/tmp/ssh-????????????/agent.*
Run Code Online (Sandbox Code Playgroud)
哪个应该匹配 file /tmp/ssh-abcdefghijkl/agent.1234。即使文件存在,脚本也不会扩展模式,而是变量包含文字模式:
echo $SSH_AUTH_SOCK
/tmp/ssh-????????????/agent.*
Run Code Online (Sandbox Code Playgroud)
但是当我从命令行做同样的事情时,它扩展了模式:
sh -c 'SSH_AUTH_SOCK=/tmp/ssh-????????????/agent.* ; echo $SSH_AUTH_SOCK'
/tmp/ssh-abcdefghijkl/agent.1234
Run Code Online (Sandbox Code Playgroud)
为什么模式扩展(通配符匹配)在我的脚本中不起作用?