社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Git

Git标记在post receive hook中[重复]

Romnick Susa • 4 年前 • 612 次点击  

我有一个非常简单的脚本,如下所示:

#!/bin/bash

VAR1="$1"
MOREF='sudo run command against $VAR1 | grep name | cut -c7-'

echo $MOREF

当我从命令行运行这个脚本并将参数传递给它时,我不会得到任何输出。但是,当我运行包含在 $MOREF 变量,我可以得到输出。

如何获取需要在脚本中运行的命令的结果,将其保存到变量中,然后在屏幕上输出该变量?

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/47957
 
612 次点击  
文章 [ 14 ]  |  最新文章 4 年前
cafebabe1991
Reply   •   1 楼
cafebabe1991    4 年前

如果试图执行的命令失败,它会将输出写入错误流,然后打印到控制台。为了避免这种情况,必须重定向错误流

result=$(ls -l something_that_does_not_exist 2>&1)
François Maturel Harshil
Reply   •   2 楼
François Maturel Harshil    5 年前

还有两种方法:

请记住,空间在 是的。因此,如果希望运行命令,请按原样使用,而不要引入任何空格。

  1. 下面将harshil赋值给l,然后打印它

    L=$"harshil"
    echo "$L"
    
  2. 下面指定命令的输出 tr 到L2。 tr公司 正在另一个变量l1上操作。

    L2=$(echo "$L1" | tr [:upper:] [:lower:])
    
Gus
Reply   •   3 楼
Gus    8 年前

有些人可能觉得这很有用。 变量替换中的整数值,技巧是使用 $(()) 双括号:

N=3
M=3
COUNT=$N-1
ARR[0]=3
ARR[1]=2
ARR[2]=4
ARR[3]=1

while (( COUNT < ${#ARR[@]} ))
do
  ARR[$COUNT]=$((ARR[COUNT]*M))
  (( COUNT=$COUNT+$N ))
done
Pratik Patil
Reply   •   4 楼
Pratik Patil    8 年前

你可以使用回勾号(也称为重音坟墓)或 $() 是的。 就像-

OUTPUT=$(x+2);
OUTPUT=`x+2`;

两者都有同样的效果。但是output=$(x+2)更可读,而且是最新的。

Aquarius Power
Reply   •   5 楼
Aquarius Power    8 年前

这是另一种方法,很适合与一些文本编辑器一起使用,这些编辑器无法正确地突出显示您创建的每个复杂代码。

read -r -d '' str < <(cat somefile.txt)
echo "${#str}"
echo "$str"
tripleee Diego Velez
Reply   •   6 楼
tripleee Diego Velez    5 年前

你需要使用

$(command-here)

`command-here`

例子

#!/bin/bash

VAR1="$1"
VAR2="$2"

MOREF="$(sudo run command against "$VAR1" | grep name | cut -c7-)"

echo "$MOREF"
Jahid
Reply   •   7 楼
Jahid    8 年前

如果要使用多行/多个命令执行此操作,则可以执行以下操作:

output=$( bash <<EOF
#multiline/multiple command/s
EOF
)

或:

output=$(
#multiline/multiple command/s
)

例子:

#!/bin/bash
output="$( bash <<EOF
echo first
echo second
echo third
EOF
)"
echo "$output"

输出:

first
second
third

使用 heredoc 通过将长的单行代码分解为多行代码,可以非常容易地简化工作。另一个例子:

output="$( ssh -p $port $user@$domain <<EOF 
#breakdown your long ssh command into multiline here.
EOF
)"
Emil
Reply   •   8 楼
Emil    6 年前

设置变量时,请确保 没有空格 = 签字。真的花了一个小时去想办法,尝试各种各样的解决方案!这不酷。

对的:

WTFF=`echo "stuff"`
echo "Example: $WTFF"

会失败的 有错误:(材料:未找到或类似)

WTFF= `echo "stuff"`
echo "Example: $WTFF"
DigitalRoss
Reply   •   9 楼
DigitalRoss    13 年前

只是为了与众不同:

MOREF=$(sudo run command against $VAR1 | grep name | cut -c7-)
BoltClock MLSC
Reply   •   10 楼
BoltClock MLSC    9 年前

我知道三种方法:

1)功能适用于此类任务:

func (){
ls -l
}

通过说 func

2)另一个合适的解决方案是评估:

var="ls -l"
eval $var

3)第三种方法是直接使用变量:

var=$(ls -l)
OR
var=`ls -l`

可以很好地得到第三种溶液的输出:

echo "$var"

而且还以令人讨厌的方式:

echo $var
F. Hauri
Reply   •   11 楼
F. Hauri    5 年前

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

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

Peter Mortensen bitwelder
Reply   •   12 楼
Peter Mortensen bitwelder    5 年前

正如他们已经告诉你的,你应该使用“反勾”。

提出的替代方案 $(command) 也可以工作,而且也更容易阅读,但请注意,它仅对bash或kornshell(以及从这些派生的shell)有效, 因此,如果您的脚本必须在各种unix系统上真正可移植,那么您应该更喜欢使用旧的backticks符号。

Peter Mortensen bitwelder
Reply   •   13 楼
Peter Mortensen bitwelder    5 年前

正确的方法是

$(sudo run command)

如果你要用撇号,你需要 ` ,不是 ' 是的。这个字符叫做“backticks”(或“grave重音”)。

这样地:

#!/bin/bash

VAR1="$1"
VAR2="$2"

MOREF=`sudo run command against "$VAR1" | grep name | cut -c7-`

echo "$MOREF"
Bob Stein Andy Lester
Reply   •   14 楼
Bob Stein Andy Lester    4 年前

除了反勾 `command` 你可以用 $(command) "$(command)" 我觉得它更容易阅读,并且允许嵌套。

OUTPUT="$(ls -1)"
echo "${OUTPUT}"

MULTILINE=$(ls \
   -1)
echo "${MULTILINE}"

引用( " )保留多行值很重要。