私信  •  关注

F. Hauri

F. Hauri 最近创建的主题
F. Hauri 最近回复了
5 年前
回复了 F. Hauri 创建的主题 » Git标记在post receive hook中[重复]

一些 我用来从命令设置变量的技巧

第二次编辑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在主进程完成时关闭。