이는 다음과 관련이 있습니다.원격 명령을 실행하고 로컬 파일을 입력으로 전달하는 방법은 무엇입니까?
나는 파일의 첫 번째 줄을 인쇄하는 간단한 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) 원격 컴퓨터에 있는 원격 디렉터리를 로컬 컴퓨터에 마운트합니다. 이는 필요한 설정에 가장 가까운 솔루션입니다. 이를 통해 로컬에서 파일을 변경할 수 있으며 원격 컴퓨터에 변경 사항이 표시됩니다. 원격 디렉터리 마운트에 대한 자세한 내용은 이 답변을 참조하세요.
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();
}
}