crontab에서 실행할 때 스크립트에서 호출된 어셈블러가 특정 파일을 생성하지 않는 이유는 무엇입니까?

crontab에서 실행할 때 스크립트에서 호출된 어셈블러가 특정 파일을 생성하지 않는 이유는 무엇입니까?

나는 사용하고있다이 스크립트내가 개발한 일부 애플리케이션을 빌드하고 패키지화합니다. 스크립트의 전체 내용은 끝에 나열되어 있습니다.

이 crontab 항목에 의해 호출됩니다.50 23 * * * nice $HOME/update-dl-wwwecm $HOME | tee -a $HOME/build-dl-wwwecm/log

디버깅을 위해 스크립트를 테스트 디렉터리에 복사 ~/test/20211101/t/하고 약간 편집했습니다. (스크립트 끝에 하드코딩된 일부 패키지를 제거하는 것과 같습니다.) 또한 이 테스트 디렉터리에서 수동으로 mkdir build-dl-wwwecm다음 mkdir webrepos저장소 hg clonewebrepos하위 디렉터리로 가져옵니다.

  1. lmacros 매크로 컬렉션(이것은 다른 것을 빌드하는 데 필요합니다. 그리고 업데이트할 첫 번째 저장소로 나열되어야 합니다.)

  2. l시계 애플리케이션

  3. KEEPHOOK 유틸리티

  4. SHUFHOOK 유틸리티

다음으로 다음과 같이 crontab에 "매분" 줄을 추가했습니다.* * * * * nice $HOME/test/20211101/t/update-dl-wwwecm $HOME/test/20211101/t | tee -a $HOME/test/20211101/t/build-dl-wwwecm/log

업데이트 스크립트는 webrepos 하위 디렉터리의 저장소에서 들어오는 커밋을 확인합니다. 그런 다음 새 커밋을 가져오고 mak.sh빌드 디렉터리 트리에 있는 모든 스크립트 파일에 대해 해당 파일의 디렉터리로 변경하고 해당 파일을 실행합니다. 이것은mak.shKEEPHOOK 전체 내용:

#! /bin/bash
nasm -I ../lmacros/ -f bin transien.asm -l keephook.lst -o keephook.com "$@"

이제 내가 관찰한 것은 내 사용자로 로그인한 업데이트 스크립트를 직접 호출하면(ssh를 통해, 화면 내에서 bash를 실행하고, ConnectBot 앱으로 서버에 연결됨) 모든 것이 예상대로 작동한다는 것입니다. 명령은 다음과 같습니다. hg -R build-dl-wwwecm/keephook strip tip(그래서 업데이트 스크립트는 끌어올 새 커밋을 찾습니다.) 그런 다음 ./update-dl-wwwecm "$PWD"(BASE에 대한 매개변수를 테스트 디렉터리로 지정하여 실제로 업데이트를 수행합니다.)

그러나 동일한 스크립트가 crontab에서 호출되면 한 가지 다릅니다. NASM은 완료된 것처럼 보이는 목록 파일을 keephook.com생성하지만 출력 파일을 삭제한 다음 생성하지 않는 것처럼 보입니다. keephook.lst로그 파일에 오류나 경고가 없습니다. 다른 모든 응용 프로그램은 잘 구축되었습니다.

그 이유와 해결 방법은 무엇입니까?


전체 업데이트 스크립트는 다음과 같습니다.

#! /bin/bash

# Usage of the works is permitted provided that this
# instrument is retained with the works, so that any entity
# that uses the works is notified of this instrument.
#
# DISCLAIMER: THE WORKS ARE WITHOUT WARRANTY.

BASE="$1"
if [[ -z "$BASE" ]]
then
  echo "Error: No base specified." >&2
  exit 1
fi
SDIR="$BASE"/webrepos
[[ -n "$2" ]] && BASE="$2"
BDIR="$BASE"/build-dl-wwwecm
TDIR="$BASE"/wwwecm/download
ODIR="$BASE"/wwwecm/download/old

[[ ! -d "$BDIR" ]] && mkdir -p "$BDIR"
[[ ! -d "$TDIR" ]] && mkdir -p "$TDIR"
[[ ! -d "$ODIR" ]] && mkdir -p "$ODIR"

function update() {
    # $1 = path below BDIR
    # $2 = "-r" if there is a branch
    # $3 = branch name if there is a branch
  if [[ ! -d "$BDIR"/"$1" ]]
  then
    hg init "$BDIR"/"$1"
  fi
  cd "$BDIR"/"$1"
  if var="$(hg incoming "$SDIR"/"$1" $2 $3)"; then
    echo "$var"
    hg pull "$SDIR"/"$1" $2 $3 && hg up $3
    find . -name mak.sh -print0 | \
      ONE="$1" xargs -r0 bash -c \
        'for file; do echo === "$ONE"/"$file"; (cd "${file%/*}"; "./${file##*/}"); done' scriptlet
    if [[ -f "$TDIR"/"$1".zip ]]
    then
      [[ ! -d "$ODIR"/"$1" ]] && mkdir -p "$ODIR"/"$1"
      datestamp="$(date -r "$TDIR"/"$1".zip +%Y%m%d)"
      echo === mv --backup=numbered "$TDIR"/"$1".zip "$ODIR"/"$1"/"$datestamp".zip
      mv --backup=numbered "$TDIR"/"$1".zip "$ODIR"/"$1"/"$datestamp".zip
    fi
    echo === zipping "$1"
    7za a -mm=deflate -mx=9 -tzip "$TDIR"/"$1".zip *
  fi
}

update lmacros
update keephook
update shufhook
update rxansi
update lclock
update seekext
update tsr
update fdapm
update renumber
touch "$BDIR"/lastrun

답변1

질문을 작성하는 동안 알아냈습니다. mak 스크립트의 stderr을 stdout으로 리디렉션하지 않았기 때문에 NASM의 오류 메시지가 tee. (cron에서 보낸 이메일과 어셈블러 목록 파일에서 발견되었는데 이전에는 오류 메시지를 확인할 생각도 하지 않았습니다. 또한 NASM이 오류 시 목록 파일을 삭제한다는 잘못된 가정을 하고 있었습니다.)

사용자로 실행하는 것과 crontab에서 실행하는 것의 이상한 차이점은 PATH( NASM version 2.14crontab의 경우, NASM version 2.15.03 compiled on Dec 28 2020내 쉘 세션의 경우)에 따라 사용되는 NASM 버전이 다르기 때문입니다. 그들은 그 점에서 다릅니다lea di지시키워드를 사용하는 word것은 이전 버전에서는 거부되었지만 최신 버전에서는 허용됩니다.

업데이트 스크립트에 대한 수정 사항은 다음과 같습니다.2>&1리디렉션을 추가하려면mak 스크립트를 실행하는 명령에.

관련 정보