광 디스크에 백업하려는 디렉토리 트리가 있습니다. 불행히도, 그것은 하나의 디스크 크기를 초과합니다 (약 60GB). 이 트리를 하드 링크 또는 기타가있는 적절한 크기의 덩어리로 나눌 스크립트를 찾고 있습니다 (원본은 그대로 유지). 그런 다음 이러한 바이트 크기의 트리를 백업 프로세스에 공급할 수 있습니다 (PAR2 중복성 추가 등).
멋진 스크립트는 아니지만 이미 완료된 것 같습니다. 제안?
(파일을 굽기 전에 더 많은 작업을 원하기 때문에 한 번에 스패닝 및 쓰기 작업을 수행 할 필요가 없습니다.)
답변
이를 위해 설계된 응용 프로그램이 있습니다. dirsplit
일반적으로 cdrkit
또는 dirsplit
패키지에 있습니다.
K3b 또는 기타 GUI 소프트웨어를 사용하여 DVD를 쉽게 만들 수있는 링크가있는 즉시 사용 가능한 폴더를 만들 수 있습니다.
답변
내가 작성한 도구 (BSD-licensed) fpart 를 사용해보십시오 :
https://sourceforge.net/projects/fpart/
답변
한때 비슷한 목적으로 못생긴 대본을 만들었습니다. 그것은 단지 kludge이지만, 작성했을 때 나는 실행 시간이나 예쁘기를 신경 쓰지 않았습니다. 나는 같은 개념의 더 “생산 된”버전이 있다고 확신하지만, 해킹을 시작하기 위해 아이디어 나 무언가를 얻으려면 여기에 간다 (2008 년 했으므로 자신의 위험 부담으로 사용하십시오!) :- )
#!/bin/sh -
REPO=/export/foton/PictureStore
LINKS=/export/foton/links
SPLITTIX=`date '+%y%m%d-%H%M'`
# kilobytes
DVDSIZE=4400000
PARTPREFIX="DVD-"
REPOSIZE=`du -sk -- ${REPO} | awk '{print $1}'`
NUMPARTS=`expr $REPOSIZE / $DVDSIZE`
SPLITDIR=${LINKS}/splits/${SPLITTIX}
mkdir -p -- "$SPLITDIR"
PARTNUM=1
PARTSIZ=0
DONESIZ=0
PARTNUM=`echo $PARTNUM | awk '{printf("%03x", $0)}'`
mkdir -p -- "${SPLITDIR}/${PARTPREFIX}${PARTNUM}"
for D in "${REPO}"/..?* "${REPO}"/.[!.]* "${REPO}"/*
do
if [ ! -e "$D" ]; then continue; fi # skip ..?*, .[!.]* and * if there are no matching files
D=${D#$REPO/}
D_SIZ=`du -sk -- "${REPO}/$D" | awk '{print $1}'`
if test `expr $D_SIZ + $PARTSIZ` -le $DVDSIZE
then
# link to D in this part
ln -s -- "$REPO/$D" "${SPLITDIR}/${PARTPREFIX}${PARTNUM}/$D"
# adjust counters
PARTSIZ=`expr $PARTSIZ + $D_SIZ`
DONESIZ=`expr $DONESIZ + $D_SIZ`
else
# next part and link to D in that
echo PART $PARTNUM: $PARTSIZ kb '(target' $DVDSIZE 'kb)'
PARTNUM=`expr $PARTNUM + 1`
PARTNUM=`echo $PARTNUM | awk '{printf("%03x", $0)}'`
PARTSIZ=$D_SIZ
DONESIZ=`expr $DONESIZ + $D_SIZ`
mkdir -p -- "${SPLITDIR}/${PARTPREFIX}${PARTNUM}"
ln -s -- "$REPO/$D" "${SPLITDIR}/${PARTPREFIX}${PARTNUM}/$D"
fi
done
echo "wrote $DONESIZ kb in $PARTNUM parts in $SPLITDIR"
나는 삼바를 통해 디스크를 구운 창 호스트와 결과를 공유했다고 생각합니다. 위의 변경되지 않은 것을 사용하는 경우 mkisofs
심볼릭 링크를 해결하는 다른 아카이버 나 다른 아카이버 를 사용할 수 있습니다 .
답변
필자는 비슷한 문제를 해결하기 위해 스크립트를 작성했다. “배포”라고 불렀다 ( 도움말 메시지와 함께 스크립트 또는 파일 의 메인 코드를 읽 거나 패키지로 다운로드 할 수 있음 ). 그것에서 설명 :
배포 -여러 CD에 패키지 모음 배포 (특히 APT와 함께 사용하기에 적합)
설명 :`배포 ‘프로그램은 패키지 모음을 배포하기위한 CD 세트 작성과 관련된 작업을보다 쉽게 만듭니다. CD 파일 시스템 배치 (다량의 패키지를 여러 디스크로 분할 등), APT (인덱싱)에서 사용할 콜렉션 준비, ISO 이미지 작성 및 디스크 기록 등의 작업이 포함됩니다.
초기 배포 컬렉션에 대한 정기적 인 업데이트는`배포 ‘를 통해 발행 할 수 있습니다.
전체 단계를 여러 단계로 수행합니다. 한 단계에서 원본 파일에 대한 심볼릭 링크를 사용하여 furure 디스크 “레이아웃”을 생성하므로 향후 디스크 트리를 개입시키고 변경할 수 있습니다.
사용법에 대한 자세한 내용은 스크립트 또는 소스 코드를 통해 인쇄 된 도움말 메시지를 참조하십시오.
더 까다로운 사용 사례를 염두에두고 (원래 기록 된 파일 모음에 “diff”(추가 된 새 파일 세트)로 업데이트를 발행 함) 추가 초기 단계 인 “고정”이 포함됩니다. “파일 콜렉션의 현재 상태 (간단하게하기 위해 콜렉션 상태를 저장하기위한 특수 작업 장소에서 심볼릭 링크를 통해 원래 파일 콜렉션을 복제하여이를 수행합니다. 그런 다음 나중에는 향후 파일 모음의 현재 상태와이 저장된 상태간에 차이를 만들 수 있습니다. 따라서이 기능이 필요하지 않더라도이 초기 단계 인 AFAIR를 건너 뛸 수 없습니다.
또한 복잡한 트리를 잘 처리하는지 또는 파일의 일반 (한 레벨) 디렉토리 만 분할 해야하는지 여부는 확실하지 않습니다 (몇 년 전에 썼습니다). (도움말 메시지 또는 소스 코드를 확인하십시오. 시간이 좀 걸리면 조금 나중에 살펴 보겠습니다.)
APT 관련 항목은 선택 사항이므로 필요하지 않은 경우 APT에서 사용할 패키지 모음을 준비 할 수 있다는 점에주의하십시오.
물론 관심이 있으시면 언제든지 다시 작성하거나 개선을 제안하십시오.
( 패키지 에는 위에 링크 된 Git 저장소에서 제시된 코드 목록에 적용되지 않은 추가 유용한 패치가 포함되어 있습니다!)
답변
우리는이 과제의 본질이 실제로 매우 단순하다는 것을 잊지 말아야합니다. Haskell에 대한 튜토리얼에서 볼 수 있듯이 (이 작업을위한 솔루션의 작업을 중심으로 작성되었으며 점진적으로 개선되었습니다)
이제 프로그램이 어떻게 작동하고 의사 코드로 표현되는지에 대해 잠시 생각해 봅시다.
main = Read list of directories and their sizes. Decide how to fit them on CD-Rs. Print solution.
합리적으로 들리나요? 나는 그렇게 생각했다.
인생을 조금 단순화하고 지금은 프로그램 외부의 디렉토리 크기 (예 : ”
du -sb *
“)를 계산하고 stdin에서이 정보를 읽겠다고 가정 해 봅시다 .
( 히치하이커 안내서에서 Haskell까지, 1 장 )
또한 귀하의 질문에 따라 결과 디스크 레이아웃을 조정 (편집) 한 다음 도구를 사용하여 구울 수 있습니다.
파일 모음을 분할하기 위해 Haskell 튜토리얼에서 간단한 프로그램 변형을 재사용 (적응 및 재사용) 할 수 있습니다.
불행하게도,에 내가 다른 대답 여기에 언급했다고 도구 , 필수 분할 작업의 단순성이의 사용자 인터페이스의 복잡성과 bloatedness가 일치하지 않습니다 그것은 여러 가지 작업을 결합하기 위해 작성 되었기 때문에 (; 단계에서 수행하지만, 그러나 여전히 내가 생각할 수있는 가장 깨끗한 방식으로 결합되지 않았습니다).distribute
distribute
코드를 사용하는 데 도움이되도록 다음은 파일 모음을 분할하는이 “필수”작업을 수행 하는 bash 코드 distribute
( 380 행 ) 에서 발췌 한 내용입니다 .
# Splitting:
function splitMirrorDir() {
if [[ ! -d "$THIS_BASES_DIR/$BASE/$type" ]]; then
echo $"No base fixed for $type" >&2
exit 1
fi
# Getting the list of all suitable files:
local -a allFiles
let 'no = 0' ||:
allFiles=()
# no points to the next free position in allFiles
# allFiles contains the constructed list
for p in "$THIS_BASES_DIR/$BASE/$type"/*.rpm; do
if [[ ! -e "$p" ]]; then
# fail on non-existent files
echo $"Package file doesn't exist: " "$p" >&2
return 1
fi
if [[ "$ONLY_REAL_FILES" == "yes" && ! -f "$p" ]]; then
continue
fi
if [[ "$DIFF_TO_BASE" ]]; then
older_copy="$DIFF_TO_BASE/$type/${p##*/}" # using shell param expansion instead of `basename' to speed up
if [[ -h "$older_copy" || -a "$older_copy" ]]; then
continue
fi
fi
allFiles[$(( no++ ))]="$p"
done
readonly -a allFiles
# Splitting the list of all files into future disks:
#
local -a filesToEat allSizes
let 'no = 0' ||:
filesToEat=()
allSizes=($(getSize "${allFiles[@]}"))
readonly -a allSizes
# allSizes contains the sizes corrsponding to allFiles
# filesToEat hold the constructed list of files to put on the current disk
# no points to the next free position in filesToEat
# totalSize should hold the sum of the sizes
# of the files already put into filesToEat;
# it is set and reset externally.
for p in "${allFiles[@]}"; do
if (( totalsize + ${allSizes[$(( no ))]} > CDVOLUME )); then
eatFiles "${filesToEat[@]}"
filesToEat=()
finishCD
startTypedCD
fi
let "totalsize += ${allSizes[$(( no ))]}" ||:
filesToEat[$(( no++ ))]="$p"
done
eatFiles "${filesToEat[@]}"
}
function eatFiles() {
#{ oldIFS="$IFS"; IFS=$'\n'; echo "$FUNCNAME: args: " "$*" | head >&2; IFS="$oldIFS"; }
zeroDelimited "$@" | xargs -0 --no-run-if-empty \
cp -s \
--target-dir="$THIS_LAYOUTS_DIR/cd$(( cdN ))/$PREFIX/$type$DOT_SUFFIX"/ \
--
}
function startTypedCD() {
# set -x
mkdir -p "$THIS_LAYOUTS_DIR/cd$(( cdN ))/$PREFIX/$type$DOT_SUFFIX"
start_action $" %s with %s" "$(( cdN ))" "$type"
# set +x
}
function finishCD() {
이 eatFiles
함수는 미래 디스크의 레이아웃을 나뭇잎이 실제 파일에 대한 심볼릭 링크 인 트리로 준비합니다. 따라서 굽기 전에 레이아웃을 편집 할 수 있어야합니다. 이 mkisofs
유틸리티에는 심볼릭 링크를 따르는 옵션이 있으며 실제로 내 mkiso
기능 코드에 사용됩니다 .
제시된 스크립트 (물론 필요에 따라 다시 쓰고 쓸 수 있음)는 가장 간단한 아이디어를 따릅니다. 파일의 크기 (또는 더 정확하게는 패키지의 경우 distribute
)를 나열된 순서대로 합산하는 것입니다. 재 배열하지 마십시오.
“하스켈에 대한 히치하이커 안내서”는 최적화 문제를보다 심각하게 고려하여 파일을 디스크에 더 잘 맞추기 위해 (그리고 더 적은 디스크를 필요로하기 위해) 파일을 스마트하게 재배치하려고 시도하는 프로그램 변형을 제안합니다.
충분한 예비가 이미 있습니다. CD를 싸서 갑시다.
당신이 이미 알고 있듯이, 우리의 문제는 고전적인 문제입니다. 그것은이라고합니다 “배낭 문제”
( 그것을 구글 은 그것이 이미 모르는 경우. 더 100,000 이상의 링크가 있습니다).탐욕스러운 해결책부터 시작합시다 …
( 3 장 이상에서 더 읽으십시오 .)
다른 스마트 도구
데비안은 distribute
wrt 패키지 모음 보다 똑똑한 배포 CD를 만드는 도구를 사용한다고 들었 습니다. 결과는 패키지 간 종속성을 염려하고 패키지 모음을 만들려고 시도하기 때문에 더 좋습니다 . 첫 번째 디스크는 종속성으로 닫힙니다. 즉, 첫 번째 디스크의 패키지는 다른 디스크의 패키지를 필요로하지 않아야합니다 (또는 적어도 그러한 종속성의 수를 최소화해야합니다).
답변
backup2l은이 작업을 많이 수행 할 수 있습니다. 패키지를 직접 사용하지 않더라도 스크립트 아이디어를 얻을 수 있습니다.
답변
rar
아카이버는 자동으로이가있는 특정 크기의 덩어리들로 만들어 보관 분할하도록 지시 할 수 있습니다 -vsize
플래그.
지정한 디렉토리 트리를 foo
500MB의 덩어리로 아카이브
rar a backup.rar -v500m foo/