默认情况下,关联数组在函数体内声明时似乎是局部的,它们应该是全局的.以下代码
#!/bin/bash
f() {
declare -A map
map[x]=a
map[y]=b
}
f
echo x: ${map[x]} y: ${map[y]}
Run Code Online (Sandbox Code Playgroud)
产生输出:
x: y:
Run Code Online (Sandbox Code Playgroud)
而这个
#!/bin/bash
declare -A map
f() {
map[x]=a
map[y]=b
}
f
echo x: ${map[x]} y: ${map[y]}
Run Code Online (Sandbox Code Playgroud)
产生输出:
x: a y: b
Run Code Online (Sandbox Code Playgroud)
是否可以在函数中声明全局关联数组?或者可以使用什么样的解决方案?
可能重复:
C宏以创建字符串
我有一个函数接受一个类型的参数char*,比如f("string");
如果字符串参数是在函数调用中由-the-fly定义的,那么如何在字符串体内扩展宏呢?
例如:
#define COLOR #00ff00
f("abc COLOR");
Run Code Online (Sandbox Code Playgroud)
相当于
f("abc #00ff00");
Run Code Online (Sandbox Code Playgroud)
但相反,不执行扩展,并且函数从字面上接收abc COLOR.
特别是,我需要精确地扩展宏\"#00ff00\",以便这个引用的标记与传递给它的其余字符串参数连接f(),包括引号; 也就是说,预处理器必须完成他的工作并欢迎编译器将代码转换f("abc COLOR");为f("abc \"#00ff00\"");
在BASH脚本中,我们可以在后台运行多个进程,这些进程使用命名管道进行互通,在文件系统上注册FIFO.这方面的一个例子可能是:
#!/bin/bash
mkfifo FIFO
# BG process 1
while :; do echo x; done & >FIFO
# BG process 2
while :; do read; done & <FIFO
exit
Run Code Online (Sandbox Code Playgroud)
我想知道是否可以在不使用文件系统上的FIFO的情况下在脚本的后台进程之间进行相同的相互通信,也许可以使用某种文件描述符重定向.
static_assert在 的 false 分支中应丢弃以下内容if constexpr,但由于断言失败而导致编译失败:
#include <type_traits>
template <class T>
constexpr bool f() {
if constexpr (std::is_same<T, int>::value) return true;
else static_assert(false, "message");
}
int main () {
if constexpr (f<int>()) return 1;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我希望丢弃的分支if constexpr不会被评估,因为它f是用 type 实例化的int。
用 Gcc 7.2 (-std=c++17) 编译
在我的bash中test有退出状态的态度0:
$ test -n && echo true || echo false
-> true
Run Code Online (Sandbox Code Playgroud)
而
$ test -n "" && echo true || echo false
-> false
Run Code Online (Sandbox Code Playgroud)
这意味着当它根本没有收到任何参数时,它假定为非零.
案例-z正常工作:
$ test -z && echo true || echo false
-> true
$ test -z "" && echo true || echo false
-> true
Run Code Online (Sandbox Code Playgroud)
这是预期的行为吗?
在下面的测试脚本中,我运行一个基本协进程echo,在后台运行的内置协进程附加其标准输出:
#!/bin/bash
# TEST 1
coproc /bin/sleep 100
echo >&${COPROC[1]} &
Run Code Online (Sandbox Code Playgroud)
该脚本总是失败,没有明显的原因,给出输出:
./test.sh: line 4: ${COPROC[1]}: Bad file descriptor
Run Code Online (Sandbox Code Playgroud)
我想知道正确的语法是否应该是这样的(&符号在重定向之前移动):
#!/bin/bash
# TEST 2
coproc /bin/sleep 100
echo & >&${COPROC[1]}
Run Code Online (Sandbox Code Playgroud)
第二个示例似乎有效,因为它在执行过程中没有报告任何错误,但使用此语法,实际上不会执行重定向;事实上,考虑另一个测试:
#!/bin/bash
# TEST 3
/bin/echo abc & >xfile
Run Code Online (Sandbox Code Playgroud)
测试 3 创建该文件xfile,但不向其中写入任何内容。奇怪的是,在重定向后再次尝试定位&符号可以使echo工作正常:
#!/bin/bash
# TEST 4
/bin/echo abc >xfile &
Run Code Online (Sandbox Code Playgroud)
xfile测试 4 创建包含字符串 的文件abc。
了解导致coproc重定向错误的原因或正确的语法是什么?
在Bash脚本上,我想让MySQL会话在多个顺序访问中保持开放状态; 访问MySQL的常用方法是为每个SQL命令或一组命令打开一个单独的会话,例如
mysql -u user -e "show tables;"
Run Code Online (Sandbox Code Playgroud)
此方法的限制是需要双重的那些事务的原子性和锁定状态的丢失:例如,T在以下双重操作的整个长度上,不可能在表上保留锁定状态:
### Minimalistic example
data=$(mysql -e "\
lock table T write;
select col from T;
")
# ...
# parse 'data' and compute 'output' variable
# ...
mysql -e "insert into T values ($output);"
Run Code Online (Sandbox Code Playgroud)
我的解决方案是使用两个FIFO在多个访问中保持MySQL会话开放,并在后台挂起进程.
建议的解决方案:
创建一对FIFO : mkfifo IN OUT.
将MySQL客户端实例设置到位,并使用虚拟对象while来保持管道打开并防止SIGPIPE信号:
mysql --xml --batch --raw --skip-column-names \
-h "$hostname" -u "$username" "$db" >IN <OUT &
while :; do sleep 1; done <IN >OUT & …Run Code Online (Sandbox Code Playgroud) 执行以下C代码
#include <stdio.h>
int main(int argc, char **argv) {
char stdinput[10];
while (1) {
fgets(stdinput, 10, stdin);
fputs(stdinput, stdout);
}
}
Run Code Online (Sandbox Code Playgroud)
生产:
通过控制台:
./a.out
input
input
Run Code Online (Sandbox Code Playgroud)
然后等待更多输入.也就是说,它与stdout一样回应stdout,类似于cat.
通过管道:
echo input | ./a.out
input
input
input
[...]
Run Code Online (Sandbox Code Playgroud)
启动后,它会自动充斥控制台,无需互动.
这个示例程序正是我用于测试的程序; 这不是削减.我希望这两个测试的行为方式相同.发生了什么?
我在C中编写了一个简单的I/O回显程序来测试更大的真实程序的问题.这里,linux FD重定向不起作用.
回声程序(又名a.out)是:
#include <stdio.h>
int main(int argc, char **argv) {
char buff[10];
while (1) {
if (fgets(buff, 10, stdin) == NULL) break;
printf("PRINT: %s \n", buff);
}
}
Run Code Online (Sandbox Code Playgroud)
从Bash,我运行它:
$ mkfifo IN OUT
$ # this is a method to keep the pipes IN and OUT opened over time
$ while :; do read; echo Read: $REPLY >&2; sleep 1; done <OUT >IN &
$ a.out >OUT <IN &
$ echo xyz >IN
Run Code Online (Sandbox Code Playgroud)
并且没有产生输出:Bash while循环无法读取OUT …
是否可以取消引用列表中包含的变量,以获取其值?例如:
(define one 1)
(define two 2)
(define list '(one two))
(display (list-ref list 0))
Run Code Online (Sandbox Code Playgroud)
这里list-ref引用one并以字母display显示one.可以改为one取消引用同音变量包含的值吗?