crontab을 사용하여 자동으로 실행할 때 이 스크립트가 손상된 파일을 출력하는 이유는 무엇입니까?

crontab을 사용하여 자동으로 실행할 때 이 스크립트가 손상된 파일을 출력하는 이유는 무엇입니까?

폴더에서 모든 .mp3 파일을 검색하고 색인을 생성하는 스크립트가 있습니다. 그런 다음 5초 정도 기다리십시오. 그렇지 않으면 제대로 작동하지 않습니다. 마지막으로 노래 제목에서 잘못된 문자를 제거합니다.

sudo crontab을 사용하여 자동으로 실행합니다.

#!/bin/bash
#Creates index file.
find /var/www/html/uploads/Music/ -name '*.mp3' > /var/www/html/uploads/Music/songs.index | sleep 5s | sudo sed -i -e 's/\/var\/www\/html/\.\./g' /var/www/html/uploads/Music/songs.index

어떤 이유로 crontab을 실행하면 텍스트로 변환되고 다시 색인화되어야 읽을 수 있는 파일이 생성됩니다. 동일한 스크립트를 수동으로 실행하면 정상적으로 작동합니다. 내가 무엇을 놓치고 있나요?

크론탭 파일:

1 * * * * /home/aaeadmin/bin/midnightRun.bash

답변1

이것은가능한파이프라인에서 명령을 실행하고 있기 때문입니다.

파이프라인의 각 부분은 동일한 파이프라인의 다른 부분과 동시에 시작되고 실행됩니다. 이는 find해당 명령이 이 명령과 정확히 동시에 시작되었음을 의미합니다 sed. 파이프(한 명령의 표준 출력에서 ​​다음 명령의 표준 입력까지)를 통해 전달된 데이터만 다른 명령을 동기화할 수 있습니다.

또한 실제로는 그렇지 않습니다.사용배관의 배관 측면. 명령 간에는 데이터가 전달되지 않습니다.

귀하의 스크립트는 다음과 같이 작성하는 것이 가장 좋습니다.

#!/bin/bash
#Creates index file.

find /var/www/html/uploads/Music/ -name '*.mp3' > /var/www/html/uploads/Music/songs.index

sed -i -e 's/\/var\/www\/html/\.\./g' /var/www/html/uploads/Music/songs.index

여기서는 find명령이 시작되기 전에 명령 실행이 완료됩니다 sed. 또한 해당 sudo명령은 분명히 필요하지 않기 때문에 제거했습니다 ( find파일을 쓸 수 있으면 sed없이 읽고 수정할 수 있습니다 sudo).

당신이 당신을 찾으면하다sudo쓰기가 필요한 경우 songs.index대상 디렉토리에 쓰기 권한이 있는 사용자의 crontab에서 이 cron 작업을 실행하는 것이 좋습니다 /var/www/html/uploads/Music.

파이프라인 솔루션은

#!/bin/sh
#Creates index file.

find /var/www/html/uploads/Music/ -name '*.mp3' |    
sed -e 's,^/var/www/html,..,' >/var/www/html/uploads/Music/songs.index

여기, find썼다곧장명령을 실행 sed하고 sed명령 결과를 인덱스 파일에 기록합니다. 에서 으로 find의 데이터(경로 이름) 통신은 sed두 프로세스를 모두 동기화 상태로 유지합니다 sed.기다리다계속하기 전에 다음 입력 라인을 생성하는 데 사용됩니다 (또는 그 반대의 경우, find더 많은 데이터를 출력하기 전에 데이터가 처리될 때 find까지 기다립니다 sed).

또한 명령을 읽기 쉽게 만들고 sed정규식을 줄 시작 부분에 고정하고 g끝 부분에서 불필요한 플래그를 제거했습니다. 이제 find명령에서 읽기 때문에 해당 -i옵션도 제거했습니다(기술적으로 해당 -e옵션도 제거할 수 있습니다).

내가 바꾼 또 다른 것은 배선이었습니다 #!. 특정 기능을 사용하지 않으므로 bash(아마도) 더 가벼운 셸을 사용하여 스크립트를 실행할 수도 있습니다.

찾은 파일의 파일 이름을 색인에 기록하고 첫 글자를 /var/www/html바꾸 려면 ..다음에서 직접 수행할 수도 있습니다 find.

#!/bin/sh
#Creates index file.

find /var/www/html/uploads/Music/ -type f -name '*.mp3' -exec sh -c '
    for pathname do
        printf "../%s\n" "${pathname#/var/www/html/}"
    done' sh {} + >/var/www/html/uploads/Music/songs.index

find명령은 이름이 주어진 패턴과 일치하는 모든 일반 파일(예: 디렉토리 등이 아닌)의 경로 이름을 찾습니다. 이러한 경로 이름의 일괄 처리에 대해 짧은 인라인 쉘 스크립트가 호출됩니다. 스크립트는 현재 경로 이름 배치를 반복하고 약간 수정하여 인쇄합니다.

경로 이름 수정은 매개변수 대체를 통해 수행됩니다 ${pathname#/var/www/html/}. 이것삭제/var/www/html/의 값에서 시작하는 문자열입니다 $pathname. 사용된 형식 문자열은 printf이 부분이 ../.

당신은 또한 볼 수 있습니다

관련 정보