PHP中傳遞相似於「數組」格式數據到shell腳本中:shell
計算捆綁商品的價格,捆綁商品中包含多個商品,這個商品是不肯定的,咱們暫時定義爲蘋果、栗子、香蕉,價格分別爲8元/斤、10元/斤、3元/斤,重量規格定爲500g,咱們把價格當作參數傳遞給shell腳本計算總價格
如下是關於PHP部分的代碼:數組
$prices = array( "apple" => 8, "banana" => 3, "chestnut" => 10 ); $command = "bash ".ROOT_PATH."/script/test.sh "; foreach ($prices as $price) { $command .= $price." "; } $output = array(); $ret = 1; exec($command." 2>&1", $output, $ret); var_dump($command, $output, $ret);exit; // command命令爲: // bash /data/home/tina/script/test.sh 8 3 10
下面是關於test.sh腳本內容:bash
#!/bin/bash all=0 for price in $@ do all=`expr ${all} + ${price}` done echo ${all}
在場景1的狀況下,咱們修改價格爲浮點數,蘋果、栗子、香蕉價格分別爲8.8元/斤、9.9元/斤、3.5元/斤,expr表達式會報錯(expr: 參數數目錯誤),expr不支持浮點類型,這裏應該採用bc或者awk,shell腳本修改以下:app
#!/bin/bash all=0 for price in $@ do #all=$(echo ${price}+${all}|bc) all=$(awk "BEGIN{print ${all}+${price}}") done echo ${all}
在場景2的基礎上,捆綁商品如今須要變動重量,蘋果0.5KG、香蕉1KG、栗子1.5KG,則計算價格時,咱們也須要把重量的參數傳遞到shell腳本中,才能計算價格。
方案一:繼續把這些參數加在腳本以後,把參數個數一分爲二,咱們知道前面一半部分爲價格參數,後半段參數爲重量參數,修改以下:
PHP代碼部分:編輯器
$prices = array( "apple" => 8.8, "banana" => 3.5, "chestnut" => 9.9 ); $weights = array( "apple" => 1, "banana" => 2, "chestnut" => 3 ); $command = "bash ".ROOT_PATH."/script/test.sh "; foreach ($prices as $price) { $command .= $price." "; } foreach ($weights as $weight) { $command .= $weight." "; } $output = array(); $ret = 1; exec($command." 2>&1", $output, $ret); var_dump($command, $output, $ret);exit; // command命令爲: // bash /data/home/tina/script/test.sh 8.8 3.5 9.9 1 2 3
修改的shell腳本爲:unix
#!/bin/bash all=0 count=`expr ${#} / 2` countIndex=`expr ${count} + 1` for price in ${@:1:${count}} do #all=$(echo "${price}*${!countIndex}+${all}"|bc) all=$(awk "BEGIN{print ${all}+${price}*${!countIndex}}") countIndex=`expr ${countIndex} + 1` done echo ${all}
方案二:把這兩種數據進行分組,就相似於PHP的數組同樣,這樣須要在命令中將每組參數分別用單引號包裹,這樣shell則會認爲只有兩個參數,再在shell腳本中當作數組來處理,修改以下:
PHP部分:code
$prices = array( "apple" => 8.8, "banana" => 3.5, "chestnut" => 9.9 ); $weights = array( "apple" => 1, "banana" => 2, "chestnut" => 3 ); $command = "bash ".ROOT_PATH."/script/test.sh '"; //添加單引號 foreach ($prices as $price) { $command .= $price." "; } $command = trim($command) . "' '"; //添加單引號 foreach ($weights as $weight) { $command .= $weight." "; } $command = trim($command) . "'"; //添加單引號 $output = array(); $ret = 1; exec($command." 2>&1", $output, $ret); var_dump($command, $output, $ret);exit; // command命令爲: // bash /data/home/tina/script/test.sh '8.8 3.5 9.9' '1 2 3'
shell腳本修改成:排序
#!/bin/bash all=0 index=0 prices=(${1}) weights=(${2}) for price in ${prices[@]} do all=$(awk "BEGIN{ print ${price}*${weights[${index}]}+${all} }") index=`expr ${index} + 1` done echo $all
對比於方案一和方案二,從長遠看,我的認爲仍是方案二佔優點一些,易於區分:能夠明顯知道第一個參數是價格組,第二個參數是重量組,可擴展:例如後續還要增長一個折扣率的參數(折扣率分別爲0.九、0.8八、0.95),優惠券減價5元等;
對於方案一,這個count的值是不固定的,折扣率計算的話,假定每一個水果種類都有單獨的折扣率,則這個count仍是3的倍數,把除以2修改成除以3就能夠ip
#command命令爲: bash /data/home/tina/script/test.sh 8.8 3.5 9.9 1 2 3 0.9 0.88 0.95
可是對於優惠券來講,那確定是對這個捆綁商品的總體優惠了,就是單獨的一個參數,假定優惠券爲5元,繼續追加參數it
#command命令爲: 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個(能夠範圍選擇)