如何用&&处理命令(和)作为参数?

时间:2015-08-18 06:49:01

标签: bash

在我的脚本中,我希望将第一个参数作为必要的文件名,将所有其他参数作为由&&(和运算符)分隔的shell命令。

echo "${@:2}"

但是Bash会删除除第一个命令之外的所有命令。

如何解决?

#!/usr/bin/env bash
while inotifywait -q -e close_write -e delete $1; do "${@:2}"; du app; done;
./watch . g++ app.cpp -o app && time ./app && du app

3 个答案:

答案 0 :(得分:0)

亚历克斯,我对你试图用inotifywait做的事情开玩笑,但是当我尝试它时,它只会挂起并且什么也不做,因为文件在被调用时是静态的。看看你想要完成什么。 (构建,运行,测量app的磁盘使用情况)可能更容易编写脚本而不是将inotifywait放在其中间。

虽然这只是获得所需输出的基本方法。下面的脚本将源文件作为第一个参数(如果没有给出名称,则默认为app.cpp)并将使用.cpp之前的名称编译代码作为g ++输出文件名。这是一个简单的尝试,以获取您正在寻找的信息:

#!/bin/bash

src=${1:-app.cpp}   ## set the source and output (exe) names
out=${src%.cpp}

printf "\n compiling 'g++ %s -o %s'\n\n" $src $out

[ -f $out ] && rm $out      ## remove existing exe before builinding

g++ $src -o $out            ## build new exe

[ -f $out ] || {            ## validate new exe created
    printf "error: compilation failed. exiting script.\n\n"
    printf "usage:   %s source.cpp (default: app.cpp)\n\n"
    exit 1
}

[ -e $out ] || {            ## validate it is executable
    printf "error: file produced from compilation is not executable.\n"
    exit 1
}

time ./$out 2>&1                        ## compute elapsed time
exesz=$(du -h $out | awk '{print $1}')  ## store disk usage (removing name)

## print results
printf "\n Source file:  %s\n" "$src"
printf " output file:  %s\n" "$out"
printf " size of exe:  %s bytes\n\n" "$exesz"

exit 0

示例输出

$ ./watch.sh

 compiling 'g++ app.cpp -o app'

Code Running
and being timed.

real    0m0.004s
user    0m0.001s
sys     0m0.002s

 Source file:  app.cpp
 output file:  app
 size of exe:  16K bytes

我使用的测试代码是一个简单的cout

#include <iostream>

using namespace std;

int main (void) {
    cout << "Code Running" << endl << "and being timed." << endl;
    return 0;
}

合并iowaitnotify

更好地了解您要完成的任务,下面是一个附加(没有所有验证检查),它将监视您的源文件并重新编译任何更改。它也避免使用eval。有几种方法可以实现这一点,这是一种方法。如果您愿意,可以从上面的脚本中添加验证检查:

#!/bin/bash

bldcmd=( ${@:2} )   ## array for build command

while inotifywait -q -e close_write -e delete $1; do 
    echo -e "\ncompiling:  ${bldcmd[@]}"
    # eval "${@:2}"
    ${bldcmd[@]}
    time ./app
    printf "\n app size: %s\n" $(du -h app | awk '{print $1}')
done

<强>输出

$ ./watch . g++ app.cpp -o app
./ CLOSE_WRITE,CLOSE app.cpp

compiling:  g++ app.cpp -o app

Code Running (ver. 6)
and being timed.

real    0m0.003s
user    0m0.001s
sys     0m0.002s

 app size: 16K

答案 1 :(得分:0)

我不确定我是否正确地阅读了这个问题,但我认为您正在询问如何g++ app.cpp -o app && time ./app && du app管道,即重复运行&&。如果您需要执行此操作,则必须引用watch,以使其(顶级)shell不解释它,而是由watch g++ app.cpp -o app '&&' time ./app '&&' du app 调用的shell解释:

\&\&

如果您愿意,您当然可以使用反斜杠转义('&&'代替public class getlatestWinningNumberAsyncTask extends AsyncTask<String, Void, String> { Document doc2 = null; Elements TestEle = null; @Override protected String doInBackground(String... params) { try { doc2 = Jsoup.connect("http://www.singaporepools.com.sg/en/toto/Pages/results.aspx").get(); TestEle = doc2.select("table.table-striped"); Log.e("TestEle", String.valueOf(TestEle)); } catch (IOException e) { e.printStackTrace(); } return null; } @Override protected void onPostExecute(String s) { super.onPostExecute(s); } } )。

答案 2 :(得分:-1)

解决方案是eval命令。