스크립트에서 호출된 어셈블러가 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 webreposhg 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으로 리디렉션하지 않았기 때문에 tee. 하나는 오류 메시지가 있는 경우입니다. 또한 오류가 발생하면 NASM이 목록 파일을 삭제할 것이라고 잘못 생각했습니다.)

NASM version 2.14사용자로 실행하는 것과 crontab에서 실행하는 것의 이상한 차이점은 경로 (crontab의 경우, NASM version 2.15.03 compiled on Dec 28 2020쉘 세션의 경우) 에 따라 다른 NASM 버전을 사용한다는 것입니다 . 차이점은lea di지시word키워드의 사용은 이전 버전에서는 거부되지만 새 버전에서는 허용됩니다.

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

관련 정보