로컬 파일을 제공하는 동안 Java 프로그램을 원격 명령으로 호출할 수 있도록 Java 프로그램/셸 스크립트 조합을 어떻게 작성할 수 있습니까?

로컬 파일을 제공하는 동안 Java 프로그램을 원격 명령으로 호출할 수 있도록 Java 프로그램/셸 스크립트 조합을 어떻게 작성할 수 있습니까?

이는 다음과 관련이 있습니다.원격 명령을 실행하고 로컬 파일을 입력으로 전달하는 방법은 무엇입니까?

나는 파일의 첫 번째 줄을 인쇄하는 간단한 Java 프로그램을 작성했습니다.

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.OutputStreamWriter;

public class ReadFirstLine 
{
    public static void main(String[] args) throws Exception 
    {
       String filename = args[0];

       BufferedReader iR  = new BufferedReader (new FileReader(filename));
       BufferedWriter oW = new BufferedWriter(new OutputStreamWriter(System.out));

       outputWriter.write(iR.readLine());

       iR.close();
       oW.close();
    }
}

ReadFirstLine그런 다음 / usr/local/RFL/ReadFirstLine 스크립트라는 / usr/bin 디렉토리에 심볼릭 링크를 만들었습니다 .

#! /bin/bash

java -cp "/usr/local/RFL" ReadFirstLine "$1" 

(/usr/local/RFL에는 ReadFirstLine.class가 있습니다)

이제 아래와 같이 모든 디렉터리에서 ReadFirstLine을 호출할 수 있습니다.

$ ReadFirstLine simplefile.txt

다른 컴퓨터에서 동일한 스크립트를 호출하고 싶습니다. 그래서 원격 컴퓨터에서 시도합니다 -

$ ssh username@xyz ReadFirstLine < localfile.txt  

그러나 오류가 발생했습니다.

Exception in thread "main" java.io.FileNotFoundException:  (No such file or directory)
    at java.io.FileInputStream.open(Native Method)
    at java.io.FileInputStream.<init>(FileInputStream.java:146)
    at java.io.FileInputStream.<init>(FileInputStream.java:101)
    at java.io.FileReader.<init>(FileReader.java:58)
    at ReadFirstLine.main(ReadFirstLine.java:12)

이 원격 호출이 작동하도록 Java 프로그램/스크립트를 수정하려면 어떻게 해야 합니까?

답변1

저는 Java에 대해 아무것도 모르지만 개념 증명을 보여드릴 수 있습니다. 우리가 있다고 말해로컬 파일.txt:

Here is the local file.

우리가 가지고 있는 원격 컴퓨터에는원격.sh:

#!/bin/bash
cat /dev/stdin

원격 컴퓨터의 스크립트는 다음과 같은 프로그램을 호출합니다.다음에서 읽기 stdin. 그런 다음 콘텐츠를 전달합니다.로컬 파일.txtSSH 명령에:

user@local:~$ cat localfile.txt | ssh user@remote remote.sh
Here is the local file.

Java 프로그램이 읽으려고 합니다.문서파일이 원격 컴퓨터에 존재하지 않습니다. 로컬 파일을 모방해 볼 수 있다고 생각합니다.

변화원격.sh도착하다:

#!/bin/bash
cat "$@"

그리고 전화해

user@local:~$ cat localfile.txt | ssh user@remote 'remote.sh <(cat /dev/stdin)'
Here is the local file.

Java 프로그램에서 그 부분을 stdin.

추측하다다음과 같은 경우 상황이 지저분해질 수 있습니다.로컬 파일.txt셸에서 확장 가능한 것으로 해석될 수 있는 모든 항목(예: *)을 포함하지만 이는 사용자가 직접 파악해야 합니다.

답변2

문제는 쉘 리디렉션(<)이 SSH 터널을 통해 파일을 전송한다는 것입니다. Java 클래스에는 파일이 아니라 FileReader로 읽을 로컬 파일의 "파일 이름"이 포함된 문자열이 필요합니다.

파일 이름은 FileReader로 전달되지 않고 표준 입력에서 읽혀집니다.

InputStreamReader isReader = new InputStreamReader(System.in);
BufferedReader iR  = new BufferedReader (isReader);

이것을 참고로 사용하십시오: https://stackoverflow.com/questions/5724646/how-to-pipe-input-to-java-program-with-bash

이제 귀하의 수업은 다음과 같습니다:

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.OutputStreamWriter;
import java.io.InputStreamReader;

public class ReadFirstLine 
{
    public static void main(String[] args) throws Exception 
    {
       String filename = args[0];
       System.out.println(filename);

       //BufferedReader iR  = new BufferedReader (new FileReader(filename));
       InputStreamReader isReader = new InputStreamReader(System.in);
       BufferedReader iR  = new BufferedReader (isReader);

       BufferedWriter oW = new BufferedWriter(new OutputStreamWriter(System.out));

       //outputWriter.write(iR.readLine());
       System.out.println(iR.readLine());

       iR.close();
       oW.close();
    }
}

하지만 이 작업에는 반드시 다음을 사용합니다.

head -1 filename.txt

:)

답변3

정의에 따라 로컬 파일은 로컬 컴퓨터에 있습니다. Java 프로그램은 원격 컴퓨터에 있습니다. 원격 시스템은 로컬 파일에 대해 알지 못하며 어떤 프로덕션 상황에서도 해당 파일을 읽을 수 있는 권한이 없을 수 있습니다. 이 상황에 대한 세 가지 일반적인 접근 방식을 생각해 볼 수 있습니다.

1) 파일 대신 stdin에서 읽도록 Java 프로그램을 변경하십시오. 그러면 현재 구문이 $ ssh username@xyz ReadFirstLine < localfile.txt작동합니다.

2) Java 프로그램을 실행하기 전에 로컬 컴퓨터에서 원격 컴퓨터로 파일을 scp합니다. scp localfile.txt username@xyz Java 프로그램의 작업 디렉터리에 넣어야 합니다.

3) 원격 컴퓨터에 있는 원격 디렉터리를 로컬 컴퓨터에 마운트합니다. 이는 필요한 설정에 가장 가까운 솔루션입니다. 이를 통해 로컬에서 파일을 변경할 수 있으며 원격 컴퓨터에 변경 사항이 표시됩니다. 원격 디렉터리 마운트에 대한 자세한 내용은 이 답변을 참조하세요.

https://stackoverflow.com/questions/232269/how-to-mount-a-linux-directory-from-a- Different-pc-to-your-local-linux-pc

Java 프로그램에 대한 인수는 경로입니다.원격 컴퓨터에 표시된 대로.

로컬 컴퓨터에서: /directory/which/has/been/shared/localfile.txt

원격 컴퓨터에서: /path/to/mounted/directory/on/remote/host/localfile.txt

$ ssh username@xyz ReadFirstLine < /path/to/mounted/directory/on/remote/host/localfile.txt

답변4

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.OutputStreamWriter;

public class ReadFirstLine 
{
    public static void main(String[] args) throws Exception 
    {
       String filename = args[0];

       BufferedReader iR  = new BufferedReader (new FileReader(filename));
       BufferedWriter oW = new BufferedWriter(new OutputStreamWriter(System.out));

       outputWriter.write(iR.readLine());

       iR.close();
       oW.close();
    }
}

관련 정보