请选择 进入手机版 | 继续访问电脑版
绿茶科技社区
PHP中传递类似于“数组”格式数据到shell脚本中:
模拟场景1
计算捆绑商品的价格,捆绑商品中包含多个商品,这个商品是不确定的,我们暂时定义为苹果、栗子、香蕉,价格分别为8元/斤、10元/斤、3元/斤,重量规格定为500g,我们把价格当做参数传递给shell脚本计算总价格
以下是关于PHP部分的代码:
  1. $prices = array(

  2.     "apple"    => 8,

  3.     "banana"   => 3,

  4.     "chestnut" => 10

  5. );



  6. $command = "bash ".ROOT_PATH."/script/test.sh ";

  7. foreach ($prices as $price) {

  8.     $command .= $price." ";

  9. }

  10. $output = array();

  11. $ret = 1;

  12. exec($command." 2>&1", $output, $ret);

  13. var_dump($command, $output, $ret);exit;

  14. // command命令为:

  15. // bash /data/home/tina/script/test.sh 8 3 10
复制代码
下面是关于test.sh脚本内容:
  1. #!/bin/bash



  2. all=0

  3. for price in $@

  4. do

  5.     all=`expr ${all} + ${price}`

  6. done

  7. echo ${all}
复制代码
模拟场景2
在场景1的情况下,我们修改价格为浮点数,苹果、栗子、香蕉价格分别为8.8元/斤、9.9元/斤、3.5元/斤,expr表达式会报错(expr: 参数数目错误),expr不支持浮点类型,这里应该采用bc或者awk,shell脚本修改如下:
  1. #!/bin/bash



  2. all=0

  3. for price in $@

  4. do

  5.     #all=$(echo ${price}+${all}|bc)

  6.     all=$(awk "BEGIN{print ${all}+${price}}")

  7. done

  8. echo ${all}
复制代码
模拟场景3
在场景2的基础上,捆绑商品现在需要变更重量,苹果0.5KG、香蕉1KG、栗子1.5KG,则计算价格时,我们也需要把重量的参数传递到shell脚本中,才能计算价格。
方案一:继续把这些参数加在脚本之后,把参数个数一分为二,我们知道前面一半部分为价格参数,后半段参数为重量参数,修改如下:
PHP代码部分:
  1. $prices = array(

  2.     "apple"    => 8.8,

  3.     "banana"   => 3.5,

  4.     "chestnut" => 9.9

  5. );

  6. $weights = array(

  7.     "apple"    => 1,

  8.     "banana"   => 2,

  9.     "chestnut" => 3

  10. );



  11. $command = "bash ".ROOT_PATH."/script/test.sh ";

  12. foreach ($prices as $price) {

  13.     $command .= $price." ";

  14. }

  15. foreach ($weights as $weight) {

  16.     $command .= $weight." ";

  17. }



  18. $output = array();

  19. $ret = 1;

  20. exec($command." 2>&1", $output, $ret);

  21. var_dump($command, $output, $ret);exit;

  22. // command命令为:

  23. // bash /data/home/tina/script/test.sh 8.8 3.5 9.9 1 2 3
复制代码
修改的shell脚本为:
  1. #!/bin/bash



  2. all=0

  3. count=`expr ${#} / 2`

  4. countIndex=`expr ${count} + 1`



  5. for price in ${@:1:${count}}

  6. do

  7.     #all=$(echo "${price}*${!countIndex}+${all}"|bc)

  8.     all=$(awk "BEGIN{print ${all}+${price}*${!countIndex}}")

  9.     countIndex=`expr ${countIndex} + 1`

  10. done

  11. echo ${all}
复制代码
方案二:把这两种数据进行分组,就类似于PHP的数组一样,这样需要在命令中将每组参数分别用单引号包裹,这样shell则会认为只有两个参数,再在shell脚本中当做数组来处理,修改如下:
PHP部分:
  1. $prices = array(

  2.     "apple"    => 8.8,

  3.     "banana"   => 3.5,

  4.     "chestnut" => 9.9

  5. );

  6. $weights = array(

  7.     "apple"    => 1,

  8.     "banana"   => 2,

  9.     "chestnut" => 3

  10. );



  11. $command = "bash ".ROOT_PATH."/script/test.sh '"; //添加单引号

  12. foreach ($prices as $price) {

  13.     $command .= $price." ";

  14. }

  15. $command = trim($command) . "' '";  //添加单引号

  16. foreach ($weights as $weight) {

  17.     $command .= $weight." ";

  18. }

  19. $command = trim($command) . "'";  //添加单引号

  20. $output = array();

  21. $ret = 1;

  22. exec($command." 2>&1", $output, $ret);

  23. var_dump($command, $output, $ret);exit;

  24. // command命令为:

  25. // bash /data/home/tina/script/test.sh '8.8 3.5 9.9' '1 2 3'
复制代码
shell脚本修改为:
  1. #!/bin/bash



  2. all=0

  3. index=0

  4. prices=(${1})

  5. weights=(${2})



  6. for price in ${prices[@]}

  7. do

  8.     all=$(awk "BEGIN{ print ${price}*${weights[${index}]}+${all} }")

  9.     index=`expr ${index} + 1`

  10. done

  11. echo $all
复制代码
对比于方案一和方案二,从长远看,个人认为还是方案二占优势一些,易于区分:可以明显知道第一个参数是价格组,第二个参数是重量组,可扩展:例如后续还要增加一个折扣率的参数(折扣率分别为0.9、0.88、0.95),优惠券减价5元等;
对于方案一,这个count的值是不固定的,折扣率计算的话,假定每个水果种类都有单独的折扣率,则这个count还是3的倍数,把除以2修改为除以3就可以
  1. #command命令为:

  2. bash /data/home/tina/script/test.sh 8.8 3.5 9.9 1 2 3 0.9 0.88 0.95
复制代码
但是对于优惠券来说,那肯定是对这个捆绑商品的整体优惠了,就是单独的一个参数,假定优惠券为5元,继续追加参数
  1. #command命令为:

  2. bash /data/home/tina/script/test.sh 8.8 3.5 9.9 1 2 3 0.9 0.88 0.95 5
复制代码
这个时候也已经不好区分了,一连串数字,不利于后续维护,接手的人肯定一脸懵逼,这都是些什么参数啊,然后内心开始一阵吐槽,方案一想想办法也能修改count=(参数个数-1)/3,不过要是后面还有其他的需求,这个逻辑又要修改,很烦额,对于方案二,则不用修改以前的逻辑,只用追加就行,不用修改以前的逻辑,脚本就不写了,这只是举个栗子。
其实,由于工作需要,才接触到要写shell脚本,初次看到一脸懵逼,这个场景也是模拟的,实际上是要对大批量的大文件进行处理,然后边学边看,发现这些命令超级……怎么说呢?感觉就像发现了新大陆,功能强大……
记录第一次写shell脚本,嗯,就这酱紫(emmmmm……脚本未做容错处理)……

再补充学到的几个简单的命令,不能忘了……
1 dos2unix 将Windows下文件中的换行键转换成Unix下的换行键(可使用Notepad++编辑器看到window下为换行符为CR LF,unix下的换行符为LF)
2 sort 对文件按照指定规则进行排序
3 comm 将两个有序文件进行对比,可以取到差集、交集(功能很强大,然后两个文件必须是有序的,不然会报错,也就是上个sort命令排序过的文件)
4 wc 统计文件行数(其实就是统计换行符)
5 $@ 脚本的所有参数
6 $# 脚本参数个数
7 ${@:1:4} 指代脚本参数从1开始至第4个(可以范围选择)

分享到 :
0 人收藏

2 个回复

倒序浏览
老翅寒暑  金牌会员 | 2019-11-15 07:54:24
非常好,顶一下
sparkdev  高级会员 | 2019-12-2 04:36:01
求沙发
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

举报|Archiver|手机版|小黑屋|Lvchakeji Inc.  

Powered by Discuz! X3.3 © 2001-2016 Comsenz Inc.

返回顶部