Docker
交互式 shell - interactive shell
docker exec 最常见的用法。你可以使用 -it 参数启动一个交互式 shell,如 /bin/bash 或 /bin/sh,然后在容器内部执行命令
非交互式执行--用来执行预先设定的命令
单个命令
脚本和单个命令
执行脚本的shell都是“非交互式”的,但我们也有办法把它启动为“交互式”shell,方法就是在执行bash命令时,添加-i选项:
login logout exit
logout退出“登陆shell”,使用exit退出“非登录shell”
登录shell”执行的startup文件为~/.bash_profile,而“非登陆shell”执行的startup文件为~/.bashrc。
通过--noprofile选项可以阻止系统加载“profile”系列的startup文
在Docker容器中运行一个非交互式命令
如果你需要在一个正在运行的Docker容器内运行一个命令,但不需要任何交互性,可以使用不带任何标志的docker exec 命令
docker info 检查docker引擎
rostopic list 检查ros引擎
docker inspect contain_nm | grep "Running"
docker ps --filter name=nostalgic_stallman
docker ps --filter status=running --filter name=mycontain_nm
docker ps --filter status=running --filter name=^/mycontain_nm$
docker ps --filter name=^/mycontain_nm$
$(docker ps -a --filter name=^/mycontain_nm$|wc -l)==2
精确匹配 name 为 bingohuang 的容器。注意,容器实际名称,开头是有一个正斜线 /
非交互式执行docker命令
## 要在容器的某个目录下运行命令,可以使用--workdir 标志来指定目录
## 把环境变量和要运行的命令一起传入容器。-e 标志可以让你指定一个环境变量 个充满环境变量的文件,你可以用--env-file 标志来做
## 在后台运行命令:如果你不想在终端中看到命令的输出,你可以使用 -d 参数在后台运行命令
## 以特定用户身份运行命令:如果你的 Docker 容器有多个用户,你可以使用 -u 参数以特定用户身份运行命令。
docker exec contain_nm sed -n '6p' /usr/local/scene_nm/share/test/conf/fig.yaml
docker exec contain_nm sed -n '2p' /usr/local/scene_nm/share/test/conf/fig.yaml
Linux命令说明
linux系统中let命令在bash中用于计算,变量名前不用加$,可以实现自加和自减操作
let 命令用于计算赋值表达式。它允许用户在脚本中定义变量并对其进行操作,同时将结果赋值给另一个变量
arg中的运算符和操作数之间有空格,否则会产生错误
echo cut sed timeout
for in do if then else fi done
docker ros
可视化选项
gnome-terminal:启动终端
Linux 创建进程
父进程/双亲、子进程/孩子、继承
exec 系列函数则用于在当前进程中执行新程序,替换其地址空间
exec就是把老的shell给干掉,然后去干活
fork 函数用于创建一个新进程,该进程是调用进程的副本(子进程)。
子进程会继承父进程的资源,但拥有独立的地址空间和堆栈。分叉
posix后面的标准接口posix_spawn;BSD的vfork;Windows的CreateProcess
#include <pthread.h>
pthread_create并不是linux的系统调用函数,而是由 glibc实现的符合posix接口规范的线程库函数。
pthread 的底层也是基于 copy_process 实现的
SHELL
变量类型
局部变量和全局变量 shell变量和环境变量
环境变量通过setenv创建,shell变量由set命令创建
交互式shell 和 非交互式shell 登录shell 和 非登录shell
登录shell执行登录文件和环境文件 登录shell:.profile,然后$ENV
输入shell的名称启动一个新shell,新shell是一个非登录shell 非登录shell只执行环境文件 非登录shell:$ENV
内部命令和外部命令 type file
bash a.sh | source a.sh | . a.sh |exec a.sh | ./a.shell
1.bash/sh 执行脚本
两种方法 bash xxx.sh,
另外一种就是bash -c “cmd string”
Bash可以以两种模式运行,默认模式(追求灵活性)和POSIX模式(追求兼容性)
2.source 命令是 bash shell 的内置命令,从 C Shell 而来。
source 命令的另一种写法是点符号,
用法和 source 相同 source 命令会强制执行脚本中的全部命令,而忽略文件的权限
source: not found shell 的解释器不是 bash,需把 shell 的解释器更改为 bash
source命令用于在当前shell环境中执行指定的脚本,而不是在一个新的shell中
bin/sh: 1: source: not found 错误
bash -c "source setup.bash && python3 test.py "
3. ./a.sh 打开一个subshell去读取、执行a.sh,
但a.sh需要有"执行权限",可以用chmod +x添加执行权限. 和bash
4. exec命令也可实现在原进程中执行,但是同时会终止原进程,所以我在命令行中执行
exec /opt/ros/../setup.sh 链接的ssh都断开了
history 输入ctrl+R后,开始准备查找命令
Docker
docker build
docker run 启动容器时传递环境变量到容器中
docker exec 进程的环境变量其实是继承自宿主机的?
docker exec [OPTIONS] container_name COMMAND [ARG...]
OMMAND只能是一条语句,为了支持多个命令的执行,需要将多个命令连接起来交给Shell
Docker假定容器名称后面的第一个参数应该是要执行的二进制文件
docker exec myContainer bash -c 'cd ~/myproject && ls '
整条命令通过-c传给bash 即可 -c 的意思是 command,所以 bash -c 后面应该跟一个 command。
用-c参数,则bash从字符串中读入命令,如果字符串后还有变量就被设定为从$0开始的位置参数。
01.使用重定向(>>)的方式
>这样的命令是由shell完成的,不是一个单独的程序
02.tee 命令将文本从标准输入复制,并将其粘贴/写入到标准输出以及文件中。
使用其 -a 标志将文本追加到文件末尾
echo 3 | sudo tee brightness
03. 对于只接受参数的程序来说,我们可以使用xargs这个参数来接受上一个程序的管道输出
sed '1i 添加的内容' file #这是在第一行前添加字符串
sed '$i 添加的内容' file #这是在最后一行行前添加字符串
sed '$a添加的内容' file #这是在最后一行行后添加字符串
docker attach 到容器,可以看到应用程序在控制台中生成输出
`docker attach`用于附加到容器的标准输入输出流,以实时查看容器的输出和交互,不会启动新的终端, 退出容器时,会导致容器的停止。
`docker exec` 用于在容器内部执行特定的命令 进入容器并开启一个新的bash终端。 退出容器终端时,不会导致容器的停止。
linux
bash 和 zsh 里都支持进程替换(Process Substitution)
# <() 操作 类似于匿名文件
comm <(find ./ -maxdepth 1 -type f -name "test*.zip" |cut -d . -f1-2 |sort) <( find ./ -maxdepth 1 -type d -name "test*"|sort )
匿名管道-命名管道
管道:通过文件系统通信。
匿名管道
命名管道 命名管道(named pipe)--事实上命名管道同样在进程替换中被使用.
命令替换(command substitution)
命令替换的一般形式由圆括号括起的命令
>(command)
<(command)
进程替换 Process substitution(进程替换) "<" 或or ">" 与()圆括号之间是没有空格的. 如果加了空格将会引起错误信息.
进程替换能比较两个不同命令之间的输出,或者甚至相同命令不同选项的输出.
cat <(ls -l) 等同于 ls -l | cat
comm <(ls -l) <(ls -al)
The <(cmdlist) syntax is supported by both, bash and zsh.
It provides a way to pass the output of a command (cmdlist) to another command when using a pipe (|) is not possible
zsh additionally supports =(cmdlist) as possible replacement for <(cmdlist)
重定向有如下两种方法:< 和 |
命令替换
变量替换
字符替换
:sed -i s/xxxx/yyyy/g ./*.txt
:变量替换、命令替换、波浪线替换
alias别名
检查topic有没有
###检查topic有没有消息
检查topic 的消息频次
rosmsg info
rostopic list
rosbag info
步骤
是否存在-存在是否启动
检查容器的状态-确保容器都启动了
修改容器的配置
检查topic的message-确保topic都有消息
脚本
##查看容器是否存在
if [ $(docker ps -a --filter name=^/mycontain_nm.0.2$ |wc -l) == 2 ]; then
echo "Have mycontain_nm.0.2 "
else
echo "No mycontain_nm container "
fi
##查看容器是否启动
if [ $(docker ps --filter name=^/mycontain_nm.0.2$ --filter status= running|wc -l) == 2 ]; then
echo "mycontain_nm.0.2 running "
else
echo "mycontain_nm container Not running "
fi
For 循环查看多个容器是否启动running
#!/bin/bash
i=0
for file in mycontain_nm your_model.1 other_cfg_1
do
let i++
if [ $(docker ps -a --filter status=running --filter name=^$file$ |wc -l) == 2 ];then
echo "$i : $file container Running "
else
echo "$i : $file container Not Running !!"
fi
done
检查Ros 的topic 是否存在,是否有消息
#!/bin/bash
i=0
for file_nm in /mytopic_1 /mytopic_10
do
let i++
result=$(timeout 2s rostopic echo -n 2 $file_nm);
echo "$i "
if [[ $result != "" ]] ; then
echo "$i:$file_nm topic have msg" ;
else
echo "$i:$file_nm no msg !!"
fi;
done;
查看状态
################ get.sh ##############################
#!/bin/bash
test_number=$(echo $DEV_ID | cut -d '_' -f2)
echo $test_number
docker exec mycontain_nm sed -n '6p' /usr/local/fig.yaml
###############改变 #################
#!/bin/bash
test_number=$(echo $DEV_ID | cut -d '_' -f2)
echo $test_number
docker exec -e test_number=$(echo $DEV_ID | cut -d '_' -f2) mycontain_nm sed -i '3s/topic: \/info\/map_at/topic: \/info\/map_at_'${test_number}'/' /usr/local/fig.yaml
docker exec -e test_number=$(echo $DEV_ID | cut -d '_' -f2) mycontain_nm sed -i '6s/mymap: false/mymap: true/' /usr/local/fig.yaml
docker restart mycontain_nm
docker exec mycontain_nm sed -n '6p' /usr/local/fig.yaml
###说明:
Shell 中, 可以用等号 = 来定义变量。注意,等号两边不能有空格
Ros采集数据
timeout 30s rosbag record \
/CAM01/camera/image_raw \
/CAM02/camera/image_raw \
--duration=3s --split -o /data/test.bag
运行结束后查看 Ros采集的bag包
find ./ -maxdepth 1 -type f -iname "*.bag" | while read dir; do count=$(rosbag info -y -k topics $dir |wc -l); echo "$dir : $count "; done
find ./ -maxdepth 1 -type f -iname "*.bag" | while read file_nm;do cnt=$(rosbag info -y -k topics $file_nm|grep "\-\ topic" |wc -l);echo "$file_nm: $cnt";done