자바 프로그램 이 셸 스 크 립 트 와 문제 정 리 를 호출 하고 실행 합 니 다(추천)

6568 단어 자바shell각본
요약:이 글 은 알 리 바 바 기술 협회(ATA)정선 집 배경 에서 나 온 것 으로 개발 과정 에서 대부분 자바 개발 이 었 으 며 텍스트 처리 과정 에서 주로 스 크 립 트 개발 이 었 다.자바 개발 의 특징 은 우리 가 TDDL,METAQ 등 을 일찍 연결 할 수 있다 는 것 이다.스 크 립 트 개발 의 특징 은 일괄 처 리 를 할 때 매우 편리 하 다 는 것 이다.
배경
우 리 는 개발 과정 에서 대부분 자바 개발 이 고 텍스트 처리 과정 에서 주로 스 크 립 트 를 개발 합 니 다.자바 개발 의 특징 은 우리 가 TDDL,METAQ 등 을 일찍 연결 할 수 있다 는 것 이다.스 크 립 트 개발 의 특징 은 일괄 처 리 를 할 때 매우 편리 하 다 는 것 이다.얼마 전에 저 는 이런 필요 한 장면 을 만 났 습 니 다.캡 처 한 데 이 터 를 포장 한 다음 에 제 가 스 크 립 트 를 통 해 캡 처 하려 고 했 습 니 다.예 를 들 어 nodejs 에서 phantomjs 를 바탕 으로 하 는 Caperjs 파충류 입 니 다.
해결 방법
첫 번 째 문제:자바 캡 처 및 결 과 를 포장 합 니 다.
그러면 비교적 직접적인 방법 은 자바 가 각종 메시지(db,metaq 등)를 받 은 다음 에 jstorm 군집 을 통 해 스케줄 링 과 캡 처 를 하 는 것 이다.마지막 으로 캡 처 한 결 과 를 파일 에 저장 하고 셸 패키지 로 전송 합 니 다.아마도 동창 회 에서 왜 자바 호출 odps 를 직접 파일 을 저장 하지 않 느 냐 고 물 었 을 것 이다.답 은 우리 의 군집 은 hz 군집 이 아니 라 odps 를 직접 업로드 하 는 속도 가 문제 가 있 기 때문에 먼저 포장 하 는 것 이 적당 하 다 는 것 이다.(여 기 는 디자인 에 얽 매 이지 않 고 본론 으로 돌아 갑 니 다)
자바 셸 호출 방법
ProcessBuilder 를 통 해 스케줄 링 을 진행 합 니 다.
이런 방법 은 비교적 직관 적 이 고 매개 변수의 설정 도 비교적 편리 하 다.예 를 들 어 내 가 실천 하 는 코드(나 는 일부 업무 코드 를 숨 겼 다).

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;
여기에 몇 개의 매개 변 수 를 설명 할 필요 가 있다.
RUNNING_SHELL_FILE:실행 할 스 크 립 트
SHELL_FILE_DIR:실행 할 스 크 립 트 가 있 는 디 렉 터 리;물론 실행 할 스 크 립 트 를 전체 경로 로 쓸 수도 있 습 니 다.
running Status:운행 상태,0 표 지 는 정상 입 니 다.자세 한 것 은 자바 문 서 를 볼 수 있 습 니 다.
param 1,param 2,param 3:RUNNINGSHELL_FILE 스 크 립 트 에서 1,2,3 달러 를 통 해 직접 받 은 인자 입 니 다.
시스템 런 타임 을 통 해 셸 을 직접 실행 합 니 다.
이 방법 은 비교적 폭력 적 이 고 자주 사용 되 며 코드 는 다음 과 같다.

p = Runtime.getRuntime().exec(SHELL_FILE_DIR + RUNNING_SHELL_FILE + " "+param1+" "+param2+" "+param3);
p.waitFor();
우 리 는 Runtime 을 통 해 builder 가 그렇게 편리 하지 않다 는 것 을 알 게 되 었 습 니 다.특히 매개 변 수 는 빈 칸 을 추가 하여 분리 해 야 합 니 다.왜냐하면 exec 는 전체 문자열 을 셸 로 실행 하기 때 문 입 니 다.
존재 할 수 있 는 문제 및 해결 방법
위 를 통 해 당신 의 요 구 를 만족 시 킬 수 있다 고 생각한다 면 벽 에 부 딪 힐 것 입 니 다.너 는 다음 과 같은 상황 에 직면 하 게 될 것 이다.
실행 권한 없 음
이 상황 에서 우리 팀 의 주 동방 은 DTS 이전 을 하 는 과정 에서 가방 안의 셸 스 크 립 트 를 실행 해 야 하 는데 압축 을 풀 고 실행 할 수 없다 는 것 을 알 게 되 었 다.그러면 위 에 방법 대로 권한 을 부여 하도록 하 겠 습 니 다.

ProcessBuilder builder = new ProcessBuilder("/bin/chmod", "755", tempFile.getPath());
   Process process = builder.start();
   int rc = process.waitFor();
자바 진행 셸 이 돌아 오 기 를 기다 리 고 있 습 니 다.
이 문 제 는 아마 더욱 자주 만 날 것 이다.셸 스 크 립 트 에 echo 나 print 출력 이 있어 버퍼 가 다 떨 어 졌 기 때 문 입 니 다!이러한 상황 을 피하 기 위해 서 는 반드시 버퍼 를 읽 어야 한다.장점 은 셸 의 구체 적 인 운행 상태 에 대해 log 를 할 수 있다 는 것 이다.예 를 들 어 위의 나의 예 에서 나 는:

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()전에 버퍼 를 읽 고 log 를 치면 셸 이 왜 예상 한 대로 실행 되 지 않 았 는 지 볼 수 있 습 니 다.이것 은 또 하나의 장점 은 셸 에서 출력 한 결 과 를 읽 을 수 있 고 자바 코드 의 진일보 한 조작 을 편리 하 게 할 수 있다 는 것 이다.
아마도 당신 은 이 문 제 를 만 날 수 있 을 것 입 니 다.분명히 수 동 으로 실행 할 수 있 는 명령 입 니 다.자바 가 호출 한 셸 중 일부 명령 은 실행 할 수 없습니다.오류:명령 이 존재 하지 않 습 니 다!
예 를 들 어 제 가 카 스 퍼 제 이 스 를 사용 할 때 셸 을 수 동 으로 실행 할 수 있 는데 자바 호출 을 할 때 항상 오류 가 발생 하 는 것 을 발 견 했 습 니 다.버퍼 를 읽 으 면 오류 로 그 를 발견 할 수 있 습 니 다.나 는 내 가 설치 한 카 스 퍼 js 의 빈 을 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
자바 가 셸 을 호출 할 때 기본적으로 시스템 의/bin/명령 을 사용 하기 때 문 입 니 다.특히 루트 권한 으로 실 행 될 때이때,너 는/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;
이렇게 하면 문 제 를 해결 할 수 있다.
자바 호출 셸 을 통 해 포장 을 한다 면 경로 문제 에 주의해 야 합 니 다.
셸 안에 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
내 셸 이 jar 가방 에 있 으 면 어 떡 하지?
정 답 은 스트레스 를 푸 는 것 이다.위의 지시 에 따라 조작 하 다.
(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      
    }
   }
파일 처리 방법 은 간단 합 니 다.임시 파일 을 직접 터치 한 다음 에 데이터 흐름 을 기록 합 니 다.코드:

FileUtils.touch(tempjline);
tempjline.deleteOnExit();
FileOutputStream fos = new FileOutputStream(tempjline);
IOUtils.copy(ClassLoaderUtil.class.getResourceAsStream(r), fos);
fos.close();
이것 이 있 습 니 다.여러분 들 은 구 덩이 를 밟 는 것 을 줄 이 고 자바 와 스 크 립 트 간 의 상호작용 을 대담 하 게 사용 할 것 이 라 고 믿 습 니 다.자바 는 셸 을 호출 할 수 있 습 니 다.그러면 셸 은 다른 것 을 호출 하 는 것 이 편리 합 니 다.버퍼 에 지나치게 의존 하여 스 레 드 간 통신 을 하지 않도록 기억 하 세 요.이 유 는 스스로 공부 하 세 요.
총결산
자바 프로그램 이 셸 스 크 립 트 를 호출 하고 실행 하 는 것 과 문제 에 관 한 이 글 은 여기까지 소개 되 었 습 니 다.자바 호출 과 셸 스 크 립 트 를 실행 하 는 것 에 관 한 더 많은 내용 은 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 찾 아 보 세 요.앞으로 많은 지원 을 바 랍 니 다!

좋은 웹페이지 즐겨찾기