一些
bash
我用来从命令设置变量的技巧
第二次编辑2018-02-12:添加不同的方式,在下面搜索
长时间运行的任务
啊!
2018-01-25编辑:添加示例函数
(用于填充有关磁盘使用情况的变量)
第一种简单的旧的兼容方式
myPi=`echo '4*a(1)' | bc -l`
echo $myPi
3.14159265358979323844
基本兼容,第二种方式
由于嵌套可能变得很重,为此实现了括号
myPi=$(bc -l <<<'4*a(1)')
嵌套示例:
SysStarted=$(date -d "$(ps ho lstart 1)" +%s)
echo $SysStarted
1480656334
读取多个变量(使用
巴什主义
)
df -k /
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/dm-0 999320 529020 401488 57% /
如果我只是想
使用
价值:
array=($(df -k /))
你可以看到
阵列
变量:
declare -p array
declare -a array='([0]="Filesystem" [1]="1K-blocks" [2]="Used" [3]="Available" [
4]="Use%" [5]="Mounted" [6]="on" [7]="/dev/dm-0" [8]="999320" [9]="529020" [10]=
"401488" [11]="57%" [12]="/")'
然后:
echo ${array[9]}
529020
但我更喜欢这样:
{ read foo ; read filesystem size used avail prct mountpoint ; } < <(df -k /)
echo $used
529020
第一
read foo
会只是
跳过
标题行(变量
$foo
将包含类似于
Filesystem 1K-blocks Used Available Use% Mounted on
)
用于填充某些变量的示例函数:
#!/bin/bash
declare free=0 total=0 used=0
getDiskStat() {
local foo
{
read foo
read foo total used free foo
} < <(
df -k ${1:-/}
)
}
getDiskStat $1
echo $total $used $free
注:
declare
行不是必需的,只是为了可读性。
关于
sudo cmd | grep ... | cut ...
shell=$(cat /etc/passwd | grep $USER | cut -d : -f 7)
echo $shell
/bin/bash
(请避免无用
cat
啊!所以这只少了一个叉子:
shell=$(grep $USER </etc/passwd | cut -d : -f 7)
所有管道(
|
)意味着叉子。必须运行另一个进程的地方,访问磁盘、库调用等等。
所以使用
sed
对于示例,将子流程限制为仅一个
餐具
:
shell=$(sed </etc/passwd "s/^$USER:.*://p;d")
echo $shell
和
巴什主义
以下内容:
但对于很多动作,主要是小文件,
猛击
可以自己做:
while IFS=: read -a line ; do
[ "$line" = "$USER" ] && shell=${line[6]}
done </etc/passwd
echo $shell
/bin/bash
或
while IFS=: read loginname encpass uid gid fullname home shell;do
[ "$loginname" = "$USER" ] && break
done </etc/passwd
echo $shell $loginname ...
更进一步
变量拆分
…
看看我的答案
How do I split a string on a delimiter in Bash?
替代方案:减少
叉子
通过使用
后台长时间运行的任务
第二次编辑2018-02-12:
为了防止像
myPi=$(bc -l <<<'4*a(1)'
myRay=12
myCirc=$(bc -l <<<" 2 * $myPi * $myRay ")
或
myStarted=$(date -d "$(ps ho lstart 1)" +%s)
mySessStart=$(date -d "$(ps ho lstart $$)" +%s)
这项工作很好,但运行许多叉子是沉重和缓慢的。
命令如下
date
和
bc
可以做很多手术,
逐字逐句地
啊!啊!
见:
bc -l <<<$'3*4\n5*6'
12
30
date -f - +%s < <(ps ho lstart 1 $$)
1516030449
1517853288
所以我们可以利用
长跑
不需要启动一个新的
叉
每一个请求。
我们只需要一些
文件描述符
和
先进先出
为了做得好:
mkfifo /tmp/myFifoForBc
exec 5> >(bc -l >/tmp/myFifoForBc)
exec 6</tmp/myFifoForBc
rm /tmp/myFifoForBc
(当然,FD
5
和
6
必须不用!)…在那里,您可以通过以下方式使用此过程:
echo "3*4" >&5
read -u 6 foo
echo $foo
12
echo >&5 "pi=4*a(1)"
echo >&5 "2*pi*12"
read -u 6 foo
echo $foo
75.39822368615503772256
变成一个函数
newConnector
你可以找到我的
新连接器
功能开启
GitHub.Com
或在
my own site
(在github上没有,我的站点上有两个文件,函数和demo被绑定到一个文件中,这个文件可以作为源文件使用,也可以作为demo运行)
样品:
. shell_connector.sh
tty
/dev/pts/20
ps --tty pts/20 fw
PID TTY STAT TIME COMMAND
29019 pts/20 Ss 0:00 bash
30745 pts/20 R+ 0:00 \_ ps --tty pts/20 fw
newConnector /usr/bin/bc "-l" '3*4' 12
ps --tty pts/20 fw
PID TTY STAT TIME COMMAND
29019 pts/20 Ss 0:00 bash
30944 pts/20 S 0:00 \_ /usr/bin/bc -l
30952 pts/20 R+ 0:00 \_ ps --tty pts/20 fw
declare -p PI
bash: declare: PI: not found
myBc '4*a(1)' PI
declare -p PI
declare -- PI="3.14159265358979323844"
功能
myBc
允许您使用具有简单语法的后台任务,对于日期:
newConnector /bin/date '-f - +%s' @0 0
myDate '2000-01-01'
946681200
myDate "$(ps ho lstart 1)" boottime
myDate now now ; read utm idl </proc/uptime
myBc "$now-$boottime" uptime
printf "%s\n" ${utm%%.*} $uptime
42134906
42134906
ps --tty pts/20 fw
PID TTY STAT TIME COMMAND
29019 pts/20 Ss 0:00 bash
30944 pts/20 S 0:00 \_ /usr/bin/bc -l
32615 pts/20 S 0:00 \_ /bin/date -f - +%s
3162 pts/20 R+ 0:00 \_ ps --tty pts/20 fw
从那里开始,如果你想结束一个后台进程,你只需要关闭他的
FD公司
以下内容:
eval "exec $DATEOUT>&-"
eval "exec $DATEIN>&-"
ps --tty pts/20 fw
PID TTY STAT TIME COMMAND
4936 pts/20 Ss 0:00 bash
5256 pts/20 S 0:00 \_ /usr/bin/bc -l
6358 pts/20 R+ 0:00 \_ ps --tty pts/20 fw
这是不需要的,因为所有fd在主进程完成时关闭。