문제

다음과 같은 문제에 부딪쳤다 : 나는 다음을 수행하는 Linux Bash 스크립트를 작성하고있다.

  • 파일에서 줄을 읽습니다
  • 스트라이프 \n 줄 끝의 캐릭터는 방금 읽습니다
  • 거기에있는 명령을 실행하십시오

예 : commands.txt

ls
ls -l
ls -ltra
ps as

bash 파일의 실행은 첫 번째 줄을 가져 와서 실행해야하지만 \n 현재, 쉘은 "명령을 찾지 못한다 : ls"스크립트의 일부는 다음과 같다.

 read line

        if [ -n "$line" ]; then #if not empty line

                #myline=`echo -n $line | tr -d '\n'`
                #myline=`echo -e $line | sed ':start /^.*$/N;s/\n//g; t start'`

                myline=`echo -n $line | tr -d "\n"`
                $myline  #execute it

                cat $fname | tail -n+2 > $fname.txt
                mv $fname.txt $fname
        fi

내가 그렇게 묻기 전에 내가 시도한 것들이 있다고 언급했다. 솔루션이 있습니까? 나는 이것에 대해 지난 몇 시간 동안 내 두뇌를 부수고있다 ...

도움이 되었습니까?

해결책

나는 항상 좋아한다 perl -ne 'chomp and print' , 신생을 다듬기 위해. 멋지고 기억하기 쉽습니다.

예를 들어 ls -l | perl -ne 'chomp and print'

하지만

나는 그것이 당신의 문제라고 생각하지 않습니다. 파일의 명령을 쉘 스크립트에서 '읽기'로 전달하는 방법을 이해하지 못합니다.

이와 같은 내 자신의 테스트 대본으로 (test.sh)

read line
if [ -n "$line" ]; then
  $line
fi

그리고 이와 같은 샘플 입력 파일 (test.cmds)

ls 
ls -l
ls -ltra

내가 이렇게 실행하면 ./test.sh < test.cmds, 나는 현재 작업 디렉토리에서 첫 번째 명령 'ls'를 실행하는 것으로 예상되는 결과를 볼 수 있습니다.

입력 파일에 인쇄 할 수없는 추가 문자가 있습니까?

내 것이 이렇게 보인다

od -c test.cmds 
0000000    l   s      \n   l   s       -   l  \n   l   s       -   l   t
0000020    r   a  \n                                                    
0000023

아래의 의견에서 입력 파일에 캐리지 리턴 ( " r")이있을 수 있습니다. 입력 파일은 원래 DOS 형식입니까? 그렇다면 예상 결과를 달성하려면 2 바이트 DOS 라인 " r n"을 단일 바이트 UNIX ONE " n"으로 변환해야합니다.

댓글을 달린 선 중 하나에서 " n"을 " n"을 교체 하여이 작업을 수행 할 수 있어야합니다.

다른 팁

누군가 이미 Shell Commands를 실행하는 프로그램을 작성했습니다 : SH 파일

파일의 첫 번째 줄만 실행하려는 경우 : head -n 1 file |sh

문제가 마차 반환 인 경우 : tr -d '\r' <file |sh

나는 이것을 시도했다 :

read line
echo -n $line | od -x

입력 'xxxx'의 경우 다음을 얻습니다.

0000000 7878 7878

보시다시피, 아니요 \n 변수의 내용의 끝에서. 옵션으로 스크립트를 실행하는 것이 좋습니다 -x (bash -x script). 이렇게하면 모든 명령이 실행될 때 인쇄됩니다.

편집] 문제는 Windows에서 명령을 편집했다는 것입니다. 이제 파일에는 CRLF (0D0A)가 혼동되는 라인 구분 자로 포함됩니다. read (그리고 ls\r 알려진 명령이 아닙니다). 사용 dos2unix 또는 UNIX 파일로 바꾸는 것과 유사합니다.

Bash BuildIns를 사용하여 운송 반환을 최신 라인으로 교체하려고 시도 할 수도 있습니다.

line=$'a line\r' 
line="${line//$'\r'/$'\n'}" 
#line="${line/%$'\r'/$'\n'}"       # replace only at line end
printf "%s" "$line" | ruby -0777 -n -e 'p $_.to_s' 

평가 명령이 필요합니다


#!/bin/bash -x

while read  cmd
do
 if [ "$cmd" ]
 then
  eval "$cmd"
 fi
done

나는 그것을 그대로 달렸다
./script.sh <file.txt

그리고 file.txt는 다음과 같습니다.

ls
ls -l
ls -ltra
ps as

일하지는 않지만 ls, 나는 보는 것이 좋습니다 find'에스 -print0 옵션

다음 스크립트가 작동합니다 (적어도 나를 위해) :

#!/bin/bash

while read I ; do if [ "$I" ] ; then $I ; fi ; done ;
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top