Commit 37138bf4 authored by platyhouse's avatar platyhouse

.

parent 2b37a47a
#!/bin/bash
# pty_files_not_find.sh
# 지정된 패턴에 해당하지 않는 파일을 검색하는 스크립트
# 사용법:
# ./pty_files_not_find.sh "*.log" -d 10 # 현재 디렉토리에서 .log가 아닌 파일 중 10일 이상 지난 파일 검색
# ./pty_files_not_find.sh "*.txt" -r -h 24 # 하위 디렉토리까지 .txt가 아닌 파일 중 24시간 이상 지난 파일 검색
# ./pty_files_not_find.sh "./*" -zerofiles # 현재 디렉토리에서 0바이트 파일 검색
# ./pty_files_not_find.sh "*.log" -r -zerofiles # 하위 디렉토리까지 .log가 아닌 파일 중 0바이트 파일 검색
show_usage() {
echo "사용법: $0 <제외할 패턴> [옵션]"
echo ""
echo "필수 인자:"
echo " 제외할 패턴 제외할 파일 패턴 (예: *.log, *.txt, *.body 등)"
echo " *.log : .log 파일을 제외한 모든 파일"
echo " *.body : .body 파일을 제외한 모든 파일"
echo ""
echo "검색 조건 옵션:"
echo " -d 일수 지정한 일수보다 오래된 파일 검색"
echo " -h 시간 지정한 시간보다 오래된 파일 검색"
echo " -zerofiles 0바이트 파일 검색"
echo " -emptydir 빈 디렉토리 검색"
echo " -size 크기 특정 크기의 파일 검색 (예: +10M, -1k, 100c)"
echo " (+: 초과, -: 미만, 단위: c=byte, k=KB, M=MB, G=GB)"
echo " -user 사용자 특정 사용자 소유 파일 검색"
echo " -perm 권한 특정 권한의 파일 검색 (예: 777, 644)"
echo ""
echo "공통 옵션:"
echo " -r 하위 디렉토리까지 재귀적으로 검색"
echo " -t 타입 파일 타입 (f: 파일만, d: 디렉토리만, l: 심볼릭링크)"
echo " -s 파일 크기와 함께 표시"
echo " -l 상세 정보 표시 (ls -lh 형식)"
echo " -maxdepth N 검색 깊이 제한 (1: 현재 디렉토리만)"
echo " -count 개수만 표시"
echo " --delete 검색된 파일/디렉토리 삭제 (확인 후 실행)"
echo " --delete-force 검색된 파일/디렉토리 강제 삭제 (확인 없이 즉시 삭제)"
echo ""
echo "예제:"
echo " $0 '*.log' -d 10 # 현재 디렉토리의 .log가 아닌 파일 중 10일 이상 지난 파일"
echo " $0 '*.body' -r # 하위 디렉토리까지 .body가 아닌 모든 파일"
echo " $0 '*.txt' -h 24 # 현재 디렉토리의 .txt가 아닌 파일 중 24시간 이상 지난 파일"
echo " $0 '*.tmp' -zerofiles # 현재 디렉토리의 .tmp가 아닌 모든 0바이트 파일"
echo " $0 '*.log' -r -zerofiles # 하위 디렉토리까지 .log가 아닌 파일 중 0바이트 파일"
echo " $0 '*.bak' -r -emptydir # 하위 디렉토리까지 모든 빈 디렉토리 (.bak 제외)"
echo " $0 '*.log' -size +100M # .log가 아닌 파일 중 100MB 이상"
echo " $0 '*.tmp' -r -size -1k # 하위 디렉토리까지 .tmp가 아닌 파일 중 1KB 미만"
echo " $0 '*.sh' -user root # 현재 디렉토리의 .sh가 아닌 root 소유 파일"
echo " $0 '*.log' -r -d 30 -s # 하위까지 .log가 아닌 파일 중 30일 이상, 크기 표시"
echo " $0 '*.log' -d 30 --delete # 30일 이상 지난 .log가 아닌 파일 삭제 (확인 후)"
exit 1
}
# 첫 번째 인자 확인 (제외할 패턴)
if [ $# -eq 0 ]; then
echo "오류: 제외할 패턴을 지정해야 합니다."
echo ""
show_usage
fi
# 첫 번째 인자가 옵션인지 확인
if [[ "$1" == -* ]]; then
echo "오류: 첫 번째 인자는 제외할 패턴이어야 합니다."
echo ""
show_usage
fi
# 첫 번째 인자를 제외 패턴으로 설정
EXCLUDE_PATTERN="$1"
shift
# 패턴에서 경로와 파일명 분리
if [[ "$EXCLUDE_PATTERN" == */* ]]; then
# 경로가 포함된 경우
SEARCH_PATH="${EXCLUDE_PATTERN%/*}"
FILE_PATTERN="${EXCLUDE_PATTERN##*/}"
# 경로가 비어있으면 루트로 설정
if [ -z "$SEARCH_PATH" ]; then
SEARCH_PATH="/"
fi
else
# 경로가 없는 경우 현재 디렉토리
SEARCH_PATH="."
FILE_PATTERN="$EXCLUDE_PATTERN"
fi
# 기본값 설정
DAYS=""
HOURS=""
FILE_TYPE=""
SHOW_SIZE=false
SHOW_DETAIL=false
SHOW_COUNT=false
SEARCH_MODE=""
FILE_SIZE=""
FILE_USER=""
FILE_PERM=""
MAX_DEPTH="1"
RECURSIVE=false
DELETE_MODE=false
DELETE_FORCE=false
# 옵션 파싱
while [[ $# -gt 0 ]]; do
case $1 in
-d)
DAYS="$2"
SEARCH_MODE="old"
shift 2
;;
-h)
HOURS="$2"
SEARCH_MODE="old"
shift 2
;;
-zerofiles)
SEARCH_MODE="zero"
shift
;;
-emptydir)
SEARCH_MODE="emptydir"
FILE_TYPE="d"
shift
;;
-size)
FILE_SIZE="$2"
SEARCH_MODE="size"
shift 2
;;
-user)
FILE_USER="$2"
SEARCH_MODE="user"
shift 2
;;
-perm)
FILE_PERM="$2"
SEARCH_MODE="perm"
shift 2
;;
-r)
RECURSIVE=true
MAX_DEPTH=""
shift
;;
-t)
FILE_TYPE="$2"
shift 2
;;
-s)
SHOW_SIZE=true
shift
;;
-l)
SHOW_DETAIL=true
shift
;;
-maxdepth)
MAX_DEPTH="$2"
RECURSIVE=false
shift 2
;;
-count)
SHOW_COUNT=true
shift
;;
--delete)
DELETE_MODE=true
shift
;;
--delete-force)
DELETE_MODE=true
DELETE_FORCE=true
shift
;;
-help|--help)
show_usage
;;
*)
echo "오류: 알 수 없는 옵션: $1"
echo ""
show_usage
;;
esac
done
# 검색 모드가 지정되지 않은 경우 기본 검색 모드로 설정
if [ -z "$SEARCH_MODE" ]; then
SEARCH_MODE="pattern"
fi
# 검색 경로 확인
if [ ! -d "$SEARCH_PATH" ]; then
echo "오류: 검색 경로 '$SEARCH_PATH'가 존재하지 않습니다."
exit 1
fi
# 숫자 유효성 검사
if [ -n "$DAYS" ]; then
if ! [[ "$DAYS" =~ ^[0-9]+$ ]]; then
echo "오류: 일수는 숫자여야 합니다."
exit 1
fi
fi
if [ -n "$HOURS" ]; then
if ! [[ "$HOURS" =~ ^[0-9]+$ ]]; then
echo "오류: 시간은 숫자여야 합니다."
exit 1
fi
fi
# find 명령어 옵션 구성
FIND_CMD="find \"$SEARCH_PATH\""
# 최대 깊이 설정 (-r 옵션이 없고 -maxdepth도 지정되지 않은 경우 기본값 1)
if [ -n "$MAX_DEPTH" ]; then
FIND_CMD="$FIND_CMD -maxdepth $MAX_DEPTH"
fi
# 파일 패턴 적용 (제외 패턴 - 핵심 차이점)
if [ "$FILE_PATTERN" != "*" ]; then
FIND_CMD="$FIND_CMD ! -name \"$FILE_PATTERN\""
fi
# 파일 타입 옵션
if [ "$FILE_TYPE" = "f" ]; then
FIND_CMD="$FIND_CMD -type f"
elif [ "$FILE_TYPE" = "d" ]; then
FIND_CMD="$FIND_CMD -type d"
elif [ "$FILE_TYPE" = "l" ]; then
FIND_CMD="$FIND_CMD -type l"
fi
# 검색 조건 설정
SEARCH_DESC=""
case $SEARCH_MODE in
pattern)
SEARCH_DESC="패턴 제외 매칭 (제외: $FILE_PATTERN)"
;;
old)
if [ -n "$DAYS" ] && [ -n "$HOURS" ]; then
echo "오류: -d와 -h 옵션은 동시에 사용할 수 없습니다."
exit 1
fi
if [ -n "$DAYS" ]; then
FIND_CMD="$FIND_CMD -mtime +$DAYS"
SEARCH_DESC="${DAYS}일 이상 지난 파일 (제외: $FILE_PATTERN)"
else
MINUTES=$((HOURS * 60))
FIND_CMD="$FIND_CMD -mmin +$MINUTES"
SEARCH_DESC="${HOURS}시간 이상 지난 파일 (제외: $FILE_PATTERN)"
fi
;;
zero)
FIND_CMD="$FIND_CMD -type f -size 0"
SEARCH_DESC="0바이트 파일 (제외: $FILE_PATTERN)"
;;
emptydir)
FIND_CMD="$FIND_CMD -type d -empty"
SEARCH_DESC="빈 디렉토리 (제외: $FILE_PATTERN)"
;;
size)
FIND_CMD="$FIND_CMD -size $FILE_SIZE"
SEARCH_DESC="크기: $FILE_SIZE (제외: $FILE_PATTERN)"
;;
user)
FIND_CMD="$FIND_CMD -user $FILE_USER"
SEARCH_DESC="소유자: $FILE_USER (제외: $FILE_PATTERN)"
;;
perm)
FIND_CMD="$FIND_CMD -perm $FILE_PERM"
SEARCH_DESC="권한: $FILE_PERM (제외: $FILE_PATTERN)"
;;
esac
# 헤더 출력
echo "============================================"
echo "파일 검색 결과 (제외 패턴)"
echo "============================================"
echo "제외할 패턴: $EXCLUDE_PATTERN"
echo "검색 경로: $SEARCH_PATH"
echo "검색 조건: $SEARCH_DESC"
if [ "$RECURSIVE" = true ]; then
echo "재귀 검색: 예 (모든 하위 디렉토리)"
elif [ -n "$MAX_DEPTH" ]; then
echo "검색 깊이: $MAX_DEPTH"
fi
if [ -n "$FILE_TYPE" ]; then
case $FILE_TYPE in
f) echo "파일 타입: 파일만" ;;
d) echo "파일 타입: 디렉토리만" ;;
l) echo "파일 타입: 심볼릭링크만" ;;
esac
fi
echo "============================================"
echo ""
# 개수만 표시하는 경우
if [ "$SHOW_COUNT" = true ]; then
COUNT=$(eval $FIND_CMD 2>/dev/null | wc -l)
echo "총 ${COUNT}개의 항목을 찾았습니다."
exit 0
fi
# 파일 찾기 및 결과 출력
if [ "$SHOW_DETAIL" = true ]; then
# 상세 정보 표시
eval $FIND_CMD -exec ls -lhd {} \; 2>/dev/null | sort -k9
COUNT=$(eval $FIND_CMD 2>/dev/null | wc -l)
elif [ "$SHOW_SIZE" = true ]; then
# 크기와 함께 표시
eval $FIND_CMD -exec ls -lhd {} \; 2>/dev/null | awk '{print $5 "\t" $9}' | sort -k2
COUNT=$(eval $FIND_CMD 2>/dev/null | wc -l)
else
# 기본: 경로만 표시
eval $FIND_CMD 2>/dev/null | sort
COUNT=$(eval $FIND_CMD 2>/dev/null | wc -l)
fi
# 결과 요약
echo ""
echo "============================================"
echo "총 ${COUNT}개의 항목을 찾았습니다."
echo "============================================"
# 총 크기 계산 (파일인 경우만)
if [ "$SEARCH_MODE" != "emptydir" ] && ([ "$FILE_TYPE" = "f" ] || [ -z "$FILE_TYPE" ] || [ "$SEARCH_MODE" = "zero" ] || [ "$SEARCH_MODE" = "size" ]); then
TOTAL_SIZE=$(eval $FIND_CMD -type f -exec du -cb {} + 2>/dev/null | tail -1 | cut -f1)
if [ -n "$TOTAL_SIZE" ] && [ "$TOTAL_SIZE" != "0" ]; then
# 바이트를 사람이 읽기 쉬운 형식으로 변환
TOTAL_SIZE_HUMAN=$(numfmt --to=iec-i --suffix=B $TOTAL_SIZE 2>/dev/null || echo "${TOTAL_SIZE} bytes")
echo "총 파일 크기: $TOTAL_SIZE_HUMAN"
echo "============================================"
fi
fi
# 삭제 모드 처리
if [ "$DELETE_MODE" = true ]; then
if [ "$COUNT" -eq 0 ]; then
echo ""
echo "삭제할 항목이 없습니다."
exit 0
fi
# 강제 삭제가 아닌 경우 확인 받기
PROCEED_DELETE=false
if [ "$DELETE_FORCE" = true ]; then
PROCEED_DELETE=true
echo ""
echo "============================================"
echo "강제 삭제 모드: ${COUNT}개 항목을 삭제합니다."
echo "============================================"
else
echo ""
echo "============================================"
echo "경고: 위의 ${COUNT}개 항목을 삭제하시겠습니까?"
echo "============================================"
read -p "삭제하시겠습니까? (y/N): " -n 1 -r
echo ""
if [[ $REPLY =~ ^[Yy]$ ]]; then
PROCEED_DELETE=true
fi
fi
if [ "$PROCEED_DELETE" = true ]; then
echo ""
echo "삭제 중..."
DELETED_COUNT=0
FAILED_COUNT=0
# 파일 목록을 배열로 저장
mapfile -t FILES_TO_DELETE < <(eval $FIND_CMD 2>/dev/null)
# 각 파일/디렉토리 삭제
for item in "${FILES_TO_DELETE[@]}"; do
if [ -d "$item" ]; then
# 디렉토리인 경우
if rmdir "$item" 2>/dev/null; then
echo "삭제됨: $item"
((DELETED_COUNT++))
else
echo "삭제 실패: $item (디렉토리가 비어있지 않거나 권한 부족)"
((FAILED_COUNT++))
fi
else
# 파일인 경우
if rm -f "$item" 2>/dev/null; then
echo "삭제됨: $item"
((DELETED_COUNT++))
else
echo "삭제 실패: $item (권한 부족)"
((FAILED_COUNT++))
fi
fi
done
echo ""
echo "============================================"
echo "삭제 완료: ${DELETED_COUNT}개 항목"
if [ "$FAILED_COUNT" -gt 0 ]; then
echo "삭제 실패: ${FAILED_COUNT}개 항목"
fi
echo "============================================"
else
echo ""
echo "삭제가 취소되었습니다."
fi
fi
exit 0
#!/bin/sh
# ptyFileRename: rename files from <SRC_GLOB> to <DST_GLOB> safely (no argv explosion)
# 사용법: ptyFileRename "*.sucess.body" "*.success"
# 규칙: SRC/DST 패턴 각각 정확히 하나의 '*'를 포함해야 하며, '*'의 내용은 그대로 치환됩니다.
set -eu
if [ $# -ne 2 ]; then
echo "사용법: $0 \"<SRC_GLOB>\" \"<DST_GLOB>\"" >&2
echo "예시 : $0 \"*.sucess.body\" \"*.success\"" >&2
exit 1
fi
SRC_GLOB=$1
DST_GLOB=$2
DRY_RUN=${DRY_RUN:-0} # DRY_RUN=1 ptyFileRename "*.sucess.body" "*.success"
# 각 패턴이 '*'를 정확히 1개 포함하는지 확인
count_star() { printf '%s' "$1" | tr -cd '*' | wc -c | tr -d ' '; }
[ "$(count_star "$SRC_GLOB")" = "1" ] || { echo "SRC_GLOB은 '*'를 정확히 1개 포함해야 합니다: $SRC_GLOB" >&2; exit 1; }
[ "$(count_star "$DST_GLOB")" = "1" ] || { echo "DST_GLOB은 '*'를 정확히 1개 포함해야 합니다: $DST_GLOB" >&2; exit 1; }
# 패턴을 prefix/suffix로 분해
SRC_PREFIX=${SRC_GLOB%%\**}
SRC_SUFFIX=${SRC_GLOB#*\*}
DST_PREFIX=${DST_GLOB%%\**}
DST_SUFFIX=${DST_GLOB#*\*}
# 재귀적으로 검색(글롭 확장은 find가 처리; 쉘 글롭 확장은 없음)
find . -type f -name "$SRC_GLOB" -print0 |
while IFS= read -r -d '' path; do
dir=${path%/*}
base=${path##*/}
# base = SRC_PREFIX + MID + SRC_SUFFIX 에서 MID 추출
MID=${base#"$SRC_PREFIX"}
MID=${MID%"$SRC_SUFFIX"}
new_base="${DST_PREFIX}${MID}${DST_SUFFIX}"
new_path="$dir/$new_base"
# 동일 파일명 존재 시 덮어쓰기 방지
if [ -e "$new_path" ] && [ "$new_path" != "$path" ]; then
echo "SKIP (exists): $new_path" >&2
continue
fi
if [ "$DRY_RUN" = "1" ]; then
echo "DRY-RUN: mv -- $path -> $new_path"
else
echo "mv: $path -> $new_path"
mv -- "$path" "$new_path"
fi
done
#!/bin/bash
find . -type f -exec grep "$1" {} +
#!/bin/bash
ps -ax | grep "$1"
#!/bin/bash
# ptyTmuxRunMulti
# 사용법: ./ptyTmuxRunMulti "<실행 커맨드>" <세션개수> "<세션 프리픽스>"
# 예: ./ptyTmuxRunMulti "php 3_embedding.php" 30 "chunks_"
# 인자 확인
if [ $# -ne 3 ]; then
echo "사용법: $0 \"<실행 커맨드>\" <세션개수> \"<세션 프리픽스>\""
exit 1
fi
CMD="$1"
NUM_SESSIONS="$2"
PREFIX="$3"
echo "=== ${NUM_SESSIONS}개의 tmux 세션을 '${PREFIX}1' ~ '${PREFIX}${NUM_SESSIONS}' 생성 ==="
for ((i=0; i<NUM_SESSIONS; i++)); do
SESSION_NAME="${PREFIX}${i}"
# 기존 세션 종료
if tmux has-session -t "$SESSION_NAME" 2>/dev/null; then
echo "세션 ${SESSION_NAME} 이미 존재 - 종료 후 재시작"
tmux kill-session -t "$SESSION_NAME"
fi
# 새 세션 생성 후 명령 실행
tmux new-session -d -s "$SESSION_NAME"
tmux send-keys -t "$SESSION_NAME" "$CMD $i $NUM_SESSIONS" C-m
echo "✅ 세션 ${SESSION_NAME} 시작됨"
sleep 0.1
done
echo ""
echo "=== 모든 세션 시작 완료 ==="
echo ""
echo "세션 목록 확인: tmux ls"
echo "예시 접속: tmux attach -t ${PREFIX}1"
echo "모든 세션 종료:"
echo "for i in \$(seq 1 ${NUM_SESSIONS}); do tmux kill-session -t ${PREFIX}\${i}; done"
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment