bash中有个export,可以导出变量给子进程使用; 但是函数没法导出给子进程使用,如下:
DevOps
bash中有个export,可以导出变量给子进程使用; 但是函数没法导出给子进程使用,如下:
我想通过nc+bash创建一个tcp server, nc负责收发数据,bash负责处理数据,如何将nc和bash结合起来呢?
思路1: 通过nc的-c选项实现
思路2: 只要能想办法将nc的标准输入和标准输入重定向给bash脚本就行了; 我们常见的管道、进程替换都只能同时做重定向标准输入或标准输出的其中一件事情; 如:
1 |
nc -l -k -U /tmp/a.sock | while :; do read cmd echo $cmd done |
或:
1 |
while :; do read cmd echo $cmd done < <(nc -l -k -U /tmp/a.sock) |
这两个都是单向的
思路3: 我们通常使用exec来做重定向,似乎也比较麻烦
思路4: bash中提供了一个coproc关键字,似乎用在这里再合适不过了
方法1:
handler.sh
1 2 3 4 |
while :; do read cmd echo $cmd done |
server.sh
1 |
nc -l -k -U /tmp/a.sock -c handler.sh |
这里利用了nc 的-c选项;
注意:
1 |
nc -l -k -U /tmp/a.sock -c 'bash handler.sh' |
这里是通过两个文件来实现的,对于脚本程序来讲,如果一个文件能实现会方便很多;那么 nc 的 -c 选项能否接受一个bash 的function呢?直接写function显然是不行的,我们知道,环境变量是可以继承的,但是function 是不行的(参考: https://phpor.net/blog/post/9188),而且我们也不能把function赋值给一个变量; 或者可以这么实现:
1 2 3 4 5 6 7 8 9 |
if [[ $1 == "serve" ]]; then while :; do read cmd echo $cmd done exit fi nc -l -k -U /tmp/a.sock -c "$0 serve" |
但是,显得好不优雅; 而且,最大的问题就是,一不小心就可能成为fork炸弹💣
方法2:server.sh
1 2 3 4 5 6 7 8 9 10 |
#!/bin/bash coproc handler { while :; do read cmd echo $cmd done } [ -e /tmp/a.sock ] && rm -fr /tmp/a.sock nc -l -k -U /tmp/a.sock <&${handler[0]} >&${handler[1]} |
注意:
问题:
参考:
总结:
场景:
1 |
printf "%s\n" $(</proc/$pid/cmline) |
对于多个部分的命令行会打印到多行,如下:
其实,printf就是这个表现的,如下:
也就是说,最后一个 %s 是不能吃掉多余的参数的,相反, printf 是如下方式消费参数的:
1 |
for d in /proc/*;do [[ $d =~ /proc/[0-9]+ ]] && echo ${d#/proc/};done |
ls 可以list /proc 目录下所有的pid,但是线程id是list不到的,如:
我们 ls /proc 的时候,只能看到 24 这个目录,看不到25 26 27 这些目录,那么线程的信息如何访问到呢?
实际上,虽然我们不能ls /proc 看到线程,但是,如果有了线程id,还是可以通过 /proc/$thread_id 来访问的,如:
如何计算字符串中单词的数量,但是不使用wc? eg:
1 2 3 |
str="apple orange pear" arr=( $str ) echo ${#arr[@]} |
如果字符串的内容在文件中,则可以直接 read -a arr 来读入到指定数组中,然后再获取数组的长度即可
参考:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
#!/bin/bash CGROUP_DIR=/sys/fs/cgroup/memory UNLIMITTED=9223372036854771712 read mem_total <$CGROUP_DIR/memory.limit_in_bytes read mem_used <$CGROUP_DIR/memory.usage_in_bytes mem_free=$((mem_total - mem_used)) read mem_swap_total <$CGROUP_DIR/memory.memsw.limit_in_bytes read mem_swap_used <$CGROUP_DIR/memory.memsw.usage_in_bytes swap_total=$((mem_swap_total - mem_total)) swap_used=$((mem_swap_used - mem_used)) swap_free=$((swap_total - swap_used)) if [[ $mem_total = "9223372036854771712" ]];then /usr/bin/free -h && exit fi printf "%20s%20s%20s\n" total used free printf "Mem:%16s%20s%20s\n" $((mem_total/1024/1024))M $((mem_used/1024/1024))M $((mem_free/1024/1024))M printf "Swap:%15s%20s%20s\n" $((swap_total/1024/1024))M $((swap_used/1024/1024))M $((swap_free/1024/1024))M |
cfdisk is a curses-based program for partitioning any hard disk drive.
阿里云OSS比云硬盘要便宜很多,而且阿里云提供一个叫做ossfs的工具,可以将OSS挂载成本地文件系统,如果使用docker的话,也可以很容易实现一个docker volume的插件,岂不快哉!
ossfs挂载成本地文件系统后:
head -c 100 会不会很快?
测试发现,不会很快,ossfs会在/tmp目录生成一个临时文件,下载的数据远不止100字节; 所以,对于特别到的文件来讲,是受制于本地磁盘的容量的。
写入是如何实现的?写大文件时,会不会占用大量内存或本地磁盘?
写入大文件时,会在 /tmp 下创建一个临时文件(该文件打开后立即删除的,只能通过ossfs进程来看),写完后再上传到oss上; 所以,写入的文件大小同样受制于本地磁盘的容量。
ls 命令会不会快?
当目录下文件很多时,ls会非常慢。原因:ls不仅仅是一个http请求拉取文件列表,而是在拉取文件列表之后,还要通过head请求获取每个文件的元数据,假如一个目录下有几万个文件,就需要几万次请求
ossfs 将oss挂载成本地文件系统后:
https://www.cnblogs.com/zhengah/p/5889340.html
socat做Unix socket转发并抓包,不错
Hello world:
解说: