电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術(shù)文章
文章詳情頁

Java程序去調(diào)用并執(zhí)行shell腳本及問題總結(jié)(推薦)

瀏覽:21日期:2022-08-31 09:25:42

摘要: 該文章來自阿里巴巴技術(shù)協(xié)會(ATA)精選集 背景 我們在開發(fā)過程中,大部分是java開發(fā), 而在文本處理過程中,主要就是腳本進(jìn)行開發(fā)。 java開發(fā)的特點就是我們可以很早地進(jìn)行TDDL, METAQ 等等地對接; 而腳本開發(fā)的特點就是在進(jìn)行批處理的時候非常方便。

背景

我們在開發(fā)過程中,大部分是java開發(fā), 而在文本處理過程中,主要就是腳本進(jìn)行開發(fā)。 java開發(fā)的特點就是我們可以很早地進(jìn)行TDDL, METAQ 等等地對接; 而腳本開發(fā)的特點就是在進(jìn)行批處理的時候非常方便。 前陣子我遇到這么一個需求場景: 對抓取的數(shù)據(jù)進(jìn)行打包, 后來又遇到我要通過腳本進(jìn)行抓取,比如nodejs下基于phantomjs的casperjs爬蟲。

解決方法

對于第一個問題:java抓取,并且把結(jié)果打包。 那么比較直接的做法就是,java接收各種消息(db,metaq等等),然后借助于jstorm集群進(jìn)行調(diào)度和抓取。 最后把抓取的結(jié)果保存到一個文件中,并且通過調(diào)用shell打包, 回傳。 也許有同學(xué)會問, 為什么不直接把java調(diào)用odps直接保存文件,答案是,我們的集群不是hz集群,直接上傳odps速度很有問題,因此先打包比較合適。(這里不糾結(jié)設(shè)計了,我們回到正題)

java調(diào)用shell的方法

通過ProcessBuilder進(jìn)行調(diào)度

這種方法比較直觀,而且參數(shù)的設(shè)置也比較方便, 比如我在實踐中的代碼(我隱藏了部分業(yè)務(wù)代碼):

ProcessBuilder pb = new ProcessBuilder('./' + RUNNING_SHELL_FILE, param1, param2, param3); pb.directory(new File(SHELL_FILE_DIR)); int runningStatus = 0; String s = null; try { Process p = pb.start(); try { runningStatus = p.waitFor(); } catch (InterruptedException e) { } } catch (IOException e) { } if (runningStatus != 0) { } return;

這里有必要解釋一下幾個參數(shù):

RUNNING_SHELL_FILE:要運(yùn)行的腳本SHELL_FILE_DIR:要運(yùn)行的腳本所在的目錄; 當(dāng)然你也可以把要運(yùn)行的腳本寫成全路徑。runningStatus:運(yùn)行狀態(tài),0標(biāo)識正常。 詳細(xì)可以看java文檔。param1, param2, param3:可以在RUNNING_SHELL_FILE腳本中直接通過1,2,$3分別拿到的參數(shù)。

直接通過系統(tǒng)Runtime執(zhí)行shell

這個方法比較暴力,也比較常用, 代碼如下:

p = Runtime.getRuntime().exec(SHELL_FILE_DIR + RUNNING_SHELL_FILE + ' '+param1+' '+param2+' '+param3);p.waitFor();

我們發(fā)現(xiàn),通過Runtime的方式并沒有builder那么方便,特別是參數(shù)方面,必須自己加空格分開,因為exec會把整個字符串作為shell運(yùn)行。

可能存在的問題以及解決方法

如果你覺得通過上面就能滿足你的需求,那么可能是要碰壁了。你會遇到以下情況。

沒權(quán)限運(yùn)行

這個情況我們團(tuán)隊的朱東方就遇到了, 在做DTS遷移的過程中,要執(zhí)行包里面的shell腳本, 解壓出來了之后,發(fā)現(xiàn)執(zhí)行不了。 那么就按照上面的方法授權(quán)吧

ProcessBuilder builder = new ProcessBuilder('/bin/chmod', '755', tempFile.getPath()); Process process = builder.start(); int rc = process.waitFor();

java進(jìn)行一直等待shell返回

這個問題估計更加經(jīng)常遇到。 原因是, shell腳本中有echo或者print輸出, 導(dǎo)致緩沖區(qū)被用完了! 為了避免這種情況, 一定要把緩沖區(qū)讀一下, 好處就是,可以對shell的具體運(yùn)行狀態(tài)進(jìn)行l(wèi)og出來。 比如上面我的例子中我會變成:

ProcessBuilder pb = new ProcessBuilder('./' + RUNNING_SHELL_FILE, keyword.trim(), taskId.toString(), fileName); pb.directory(new File(CASPERJS_FILE_DIR)); int runningStatus = 0; String s = null; try { Process p = pb.start(); BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream())); BufferedReader stdError = new BufferedReader(new InputStreamReader(p.getErrorStream())); while ((s = stdInput.readLine()) != null) { LOG.error(s); } while ((s = stdError.readLine()) != null) { LOG.error(s); } try { runningStatus = p.waitFor(); } catch (InterruptedException e) { }

記得在start()之后, waitFor()之前把緩沖區(qū)讀出來打log, 就可以看到你的shell為什么會沒有按照預(yù)期運(yùn)行。 這個還有一個好處是,可以讀shell里面輸出的結(jié)果, 方便java代碼進(jìn)一步操作。

也許你還會遇到這個問題,明明手工可以運(yùn)行的命令,java調(diào)用的shell中某一些命令居然不能執(zhí)行,報錯:命令不存在!

比如我在使用casperjs的時候,手工去執(zhí)行shell明明是可以執(zhí)行的,但是java調(diào)用的時候,發(fā)現(xiàn)總是出錯。 通過讀取緩沖區(qū)就能發(fā)現(xiàn)錯誤日志了。 我發(fā)現(xiàn)即便自己把安裝的casperjs的bin已經(jīng)加入了path中(/etc/profile, 各種bashrc中)還不夠。 比如:

export NODE_HOME='/home/admin/node'export CASPERJS_HOME='/home/admin/casperjs'export PHANTOMJS_HOME='/home/admin/phantomjs'export PATH=$PATH:$JAVA_HOME/bin:/root/bin:$NODE_HOME/bin:$CASPERJS_HOME/bin:$PHANTOMJS_HOME/bin

原來是因為java在調(diào)用shell的時候,默認(rèn)用的是系統(tǒng)的/bin/下的指令。特別是你用root權(quán)限運(yùn)行的時候。 這時候,你要在/bin下加軟鏈了。針對我上面的例子,就要在/bin下加軟鏈:

ln -s /home/admin/casperjs/bin/casperjs casperjs;ln -s /home/admin/node/bin/node node;ln -s /home/admin/phantomjs/bin/phantomjs phantomjs;

這樣,問題就可以解決了。

如果是通過java調(diào)用shell進(jìn)行打包,那么要注意路徑的問題了

因為shell里面tar的壓縮和解壓可不能直接寫:

tar -zcf /home/admin/data/result.tar.gz /home/admin/data/result

直接給你報錯,因為tar的壓縮源必須到路徑下面, 因此可以寫成

tar -zcf /home/admin/data/result.tar.gz -C /home/admin/data/ result

如果我的shell是在jar包中怎么辦?

答案是:解壓出來。再按照上面指示進(jìn)行操作。

(1)找到路徑

String jarPath = findClassJarPath(ClassLoaderUtil.class); JarFile topLevelJarFile = null; try { topLevelJarFile = new JarFile(jarPath); Enumeration<JarEntry> entries = topLevelJarFile.entries(); while (entries.hasMoreElements()) { JarEntry entry = entries.nextElement(); if (!entry.isDirectory() && entry.getName().endsWith('.sh')) { 對你的shell文件進(jìn)行處理 } }

對文件處理的方法就簡單了,直接touch一個臨時文件,然后把數(shù)據(jù)流寫入,代碼:

FileUtils.touch(tempjline);tempjline.deleteOnExit();FileOutputStream fos = new FileOutputStream(tempjline);IOUtils.copy(ClassLoaderUtil.class.getResourceAsStream(r), fos);fos.close();

有這個這個東東,相信大家會減少踩坑,而且大膽地使用java和腳本之間的交互吧。 java可以調(diào)用shell,那么shell再調(diào)用其他就方便了。 記得一點, 不要過度地依賴緩沖區(qū)進(jìn)行線程之間的通信。原因自己去學(xué)習(xí)吧。

總結(jié)

到此這篇關(guān)于Java程序去調(diào)用并執(zhí)行shell腳本及問題總結(jié)的文章就介紹到這了,更多相關(guān)java調(diào)用并執(zhí)行shell腳本內(nèi)容請搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!

標(biāo)簽: Java
相關(guān)文章:
主站蜘蛛池模板: 污水提升器,污水提升泵,污水提升装置-德国泽德(zehnder)水泵系统有限公司 | 山东艾德实业有限公司 | 电动葫芦|环链电动葫芦-北京凌鹰名优起重葫芦 | 艾默生变频器,艾默生ct,变频器,ct驱动器,广州艾默生变频器,供水专用变频器,风机变频器,电梯变频器,艾默生变频器代理-广州市盟雄贸易有限公司官方网站-艾默生变频器应用解决方案服务商 | 刑事律师_深圳著名刑事辩护律师_王平聚【清华博士|刑法教授】 | 东莞市天进机械有限公司-钉箱机-粘箱机-糊箱机-打钉机认准东莞天进机械-厂家直供更放心! | 钢丝绳探伤仪-钢丝绳检测仪-钢丝绳探伤设备-洛阳泰斯特探伤技术有限公司 | 德州万泰装饰 - 万泰装饰装修设计软装家居馆| 砂石生产线_石料生产线设备_制砂生产线设备价格_生产厂家-河南中誉鼎力智能装备有限公司 | 工业风机_环保空调_冷风机_工厂车间厂房通风降温设备旺成服务平台 | 智慧水务|智慧供排水利信息化|水厂软硬件系统-上海敢创 | 电脑刺绣_绣花厂家_绣花章仔_织唛厂家-[源欣刺绣]潮牌刺绣打版定制绣花加工厂家 | 在线浊度仪_悬浮物污泥浓度计_超声波泥位计_污泥界面仪_泥水界面仪-无锡蓝拓仪表科技有限公司 | 代写标书-专业代做标书-商业计划书代写「深圳卓越创兴公司」 | 宏源科技-房地产售楼系统|线上开盘系统|售楼管理系统|线上开盘软件 | 新能源汽车电机定转子合装机 - 电机维修设备 - 睿望达 | 生物除臭剂-除味剂-植物-污水除臭剂厂家-携葵环保有限公司 | 南溪在线-南溪招聘找工作、找房子、找对象,南溪综合生活信息门户! | 浙江华锤电器有限公司_地磅称重设备_防作弊地磅_浙江地磅售后维修_无人值守扫码过磅系统_浙江源头地磅厂家_浙江工厂直营地磅 | 深圳激光打标机_激光打标机_激光焊接机_激光切割机_同体激光打标机-深圳市创想激光科技有限公司 深圳快餐店设计-餐饮设计公司-餐饮空间品牌全案设计-深圳市勤蜂装饰工程 | 电动葫芦-河北悍象起重机械有限公司 | 温州食堂承包 - 温州市尚膳餐饮管理有限公司| 废旧物资回收公司_广州废旧设备回收_报废设备物资回收-益美工厂设备回收公司 | 无锡不干胶标签,卷筒标签,无锡瑞彩包装材料有限公司 | 预制舱-电力集装箱预制舱-模块化预制舱生产厂家-腾达电器设备 | Magnescale探规,Magnescale磁栅尺,Magnescale传感器,Magnescale测厚仪,Mitutoyo光栅尺,笔式位移传感器-苏州连达精密量仪有限公司 | 临海涌泉蜜桔官网|涌泉蜜桔微商批发代理|涌泉蜜桔供应链|涌泉蜜桔一件代发 | 电动葫芦|手拉葫芦|环链电动葫芦|微型电动葫芦-北京市凌鹰起重机械有限公司 | 不锈钢螺丝 - 六角螺丝厂家 - 不锈钢紧固件 - 万千紧固件--紧固件一站式采购 | 高精度-恒温冷水机-螺杆式冰水机-蒸发冷冷水机-北京蓝海神骏科技有限公司 | 高铝矾土熟料_细粉_骨料_消失模_铸造用铝矾土_铝酸钙粉—嵩峰厂家 | 袋式过滤器,自清洗过滤器,保安过滤器,篮式过滤器,气体过滤器,全自动过滤器,反冲洗过滤器,管道过滤器,无锡驰业环保科技有限公司 | 智能垃圾箱|垃圾房|垃圾分类亭|垃圾分类箱专业生产厂家定做-宿迁市传宇环保设备有限公司 | 福州甲醛检测-福建室内空气检测_环境检测_水质检测-福建中凯检测技术有限公司 | 青岛代理记账_青岛李沧代理记账公司_青岛崂山代理记账一个月多少钱_青岛德辉财税事务所官网 | 环境模拟实验室_液体-气体控温机_气体控温箱_无锡双润冷却科技有限公司 | 步入式高低温测试箱|海向仪器 | 济南品牌设计-济南品牌策划-即合品牌策划设计-山东即合官网 | 电解抛光加工_不锈钢电解抛光_常州安谱金属制品有限公司 | 瓶盖扭矩测试仪-瓶盖扭力仪-全自动扭矩仪-济南三泉中石单品站 | 吸音板,隔音板,吸音材料,吸音板价格,声学材料 - 佛山诺声吸音板厂家 |