대상을 지정하지 않고 `mv ./*`는 무엇을 합니까?

대상을 지정하지 않고 `mv ./*`는 무엇을 합니까?

실수로 Enter 키를 누르기 전에 목적지를 지정하는 것을 잊어버렸습니다. mv ./*대상을 지정하지 않고 현재 디렉터리의 파일과 디렉터리를 어디로 이동합니까?

답변1

마지막 인수가 디렉토리인 경우 현재 작업 디렉토리(이름이 점으로 시작하는 파일 제외)의 모든 파일과 디렉토리를 해당 디렉토리로 이동하면 됩니다. 두 개의 파일이 있는 경우 첫 번째 파일이 두 번째 파일을 덮어쓸 수 있습니다.

다음은 몇 가지 데모입니다.

파일이 2개 이상이고 마지막 매개변수가 파일입니다.

$ mkdir d1 d2 d3
$ touch a b c e
$ mv *
mv: target 'e' is not a directory

파일이 세 개 이상이고 마지막 매개변수가 디렉터리입니다.

$ mkdir d1 d2 d3
$ touch a b c
$ mv -v *
'a' -> 'd3/a'
'b' -> 'd3/b'
'c' -> 'd3/c'
'd1' -> 'd3/d1'
'd2' -> 'd3/d2'

두 개의 파일

$ touch a b
$ mv -v *
'a' -> 'b'

추가 설명

쉘은 glob( *)을 인수로 확장합니다 mv. 글로브는 일반적으로 알파벳순으로 확장됩니다. mv항상 파일 및 디렉터리 목록을 확인하세요. 그것은 구체 자체를 결코 보지 못합니다.

이 명령은 mv두 가지 유형의 이동을 지원합니다. 하나는 mv file ... directory. 다른 하나는 mv old-file-name new-file-name(또는 mv old-file-name directory/new-file-name)입니다.

답변2

먼저 테스트 라이브러리(파일 5개와 폴더 1개)를 만듭니다.

touch file1 file2 file3 file4 file5
mkdir folder

다음으로 테스트 명령을 실행하겠습니다. 이 옵션은 -v쉘에서 실행되는 모든 명령을 에 인쇄하도록 지정 합니다 stderr.-xstderr하지만나는 끝내고 싶다뒤쪽에명령은 평가되지만앞으로실행하기 위한 쉘입니다.

sh -cxv 'echo mv *'

산출

echo mv *
+ echo mv file1 file2 file3 file4 file5 folder
mv file1 file2 file3 file4 file5 folder

그러면 제가 쉘에 제공하는 명령이 echo mv *쉘이 실행하는 명령임을 알 수 있습니다.뒤쪽에 *확장된 echo mv파일과 폴더는 모두 있습니다.

기본적으로 쉘은 확장됩니다구체좋다:

sh -cxv 'echo file[1-5]'

산출

echo file[1-5]
+ echo file1 file2 file3 file4 file5
file1 file2 file3 file4 file5

이것은 glob 함수의 결과입니다 set [+-]f.

sh -cxvf 'echo file[1-5]'

산출

echo file[1-5]
+ echo 'file[1-5]'
file[1-5]

mv *따라서 단어 로 확장되는 쉘 과 같이 기본 옵션으로 구성된 쉘에서 명령을 실행하면 *현재 디렉토리의 모든 파일에 대한 인수 목록이 로케일에 따라 정렬됩니다. 시스템 exec(ve)호출을 수행합니다.mv (본질적으로)이 매개변수 목록을 추가합니다. 따라서 mv쉘이 매개변수에 대해 전역 일치를 수행하고 이를 정렬하면 모든 매개변수를 가져옵니다. 이러한 효과를 보는 것 외에도 strace디버깅을 다시 사용할 수 있습니다. 예를 들면 다음과 같습니다.

sh -s -- mv * <<\SCRIPT
sed -n l /proc/$$/cmdline
echo "$@"
SCRIPT

산출

sh\000-s\000--\000mv\000file1\000file2\000file3\000file4\000file5\000folder\
\000$
mv file1 file2 file3 file4 file5 folder

그리고 휴대용:

( PS4= IFS=/; set -x mv *; : "/$*/" ) 2>&1

산출

: /mv/file1/file2/file3/file4/file5/folder/

기본적으로 쉘은 mv디렉토리의 내용을 사용하여 실행합니다.(비어 있지 않고 이름이 로 시작하는 파일/폴더를 포함하지 않는 경우 .)매개변수 목록으로. mv세 개 이상의 인수로 호출되는 경우 POSIX는 최종 인수가 디렉토리로 해석되도록 지정합니다 ln.(실제로 기본 기능 측면에서 매우 유사한 도구이기 때문입니다.).

하지만 충분 합니다 echo.

sh -cxv 'mv *' ; ls

산출

mv *
+ mv file1 file2 file3 file4 file5 folder
folder/

모든 파일은 폴더이기 때문에 마지막 매개변수로 이동됩니다. 폴더가 아니면 어떻게 되나요?

sh -cxv 'cd *; mv *'; ls . *

산출

cd *; mv *
+ cd folder
+ mv file1 file2 file3 file4 file5
mv: target ‘file5’ is not a directory

.:
folder/

folder:
file1  file2  file3  file4  file5

그게 다야POSIX 지정 mv이 경우 다음과 같이 동작해야 합니다.

mv [-if] source_file target_file

mv [-if] source_file... target_dir

첫 번째 요약 양식에서 mv유틸리티는 source_file 피연산자에 지정된 파일을 다음 위치로 이동해야 합니다.대상 파일. 첫 번째 요약 형식은 마지막 피연산자가 기존 디렉터리의 이름을 지정하지 않고 기존 디렉터리를 참조하는 심볼릭 링크가 아닐 때 사용됩니다. 이 경우, 만약소스 파일디렉터리가 아닌 파일의 이름을 지정하고대상 파일후행 문자로 끝나는 경우 /slash이는 mv오류로 간주되어야 하며 그렇지 않습니다.소스 파일피연산자가 처리됩니다.

두 번째 요약 형식에서는 mvsource_file 피연산자로 명명된 각 파일을 source_file 피연산자로 명명된 기존 디렉터리의 대상 파일로 이동해야 합니다.대상 디렉토리피연산자 또는 참조대상 디렉토리기존 디렉토리를 참조하는 심볼릭 링크입니다. 각 source_file의 대상 경로는 대상 디렉터리, 단일 /slash문자(대상이 a로 끝나지 않는 경우 /slash) 및 마지막 경로 이름 구성 요소의 연결입니다.소스 파일. 두 번째 형식은 마지막 피연산자가 기존 디렉터리의 이름을 지정할 때 사용됩니다.

따라서 *다음과 같이 확장하면:

  • 두 개의 파일

    • 파일은 하나만 있어야 하며, renamed두 번째 파일 이후의 첫 번째부터 두 번째 파일은 unlinked.
  • 하나 이상의 파일 뒤에 하나 이상의 파일에 대한 디렉터리 또는 링크가 옵니다.

    • 상위 항목의 이전 콘텐츠가 모두 이동된 디렉터리 또는 링크가 하나만 있어야 합니다.
  • 다른 것

    • 오류 메시지를 받고 안도의 한숨을 쉬게 됩니다.

답변3

먼저, 쉘은 ./*현재 디렉토리의 모든 파일로 확장됩니다(점으로 시작하는 파일 제외).

  • 파일이 없거나 하나만 있는 경우: mv실패
  • 두 개의 파일이 있는 경우: 첫 번째 파일이 두 번째 파일로 이동됩니다(따라서 손실됨).
  • 파일이 2개 이상인 경우:
    • 마지막 파일이 디렉터리인 경우: 모든 파일이 해당 디렉터리로 이동됩니다.
    • 그렇지 않으면 mv실패합니다.

답변4

mv *효과 는 무엇입니까 ?

짧은 답변은 다음과 같습니다.

쉘은 와일드카드 문자를 *디렉토리 내용 목록으로 확장합니다. 그러면 쉘은 이 전체 목록을 명령에 전달합니다. 이 명령은 이전에 본 적이 없습니다 *.

이 명령은 mv file1 file2 ... filen directoryfile1 ... filen을 디렉터리로 이동합니다.

여기서는 세 개의 파일이 포함된 테스트 디렉터리를 만들었습니다.

$ mkdir t
$ cd t
$ echo a>a; echo b>b; echo c>c
$ ls
a  b  c

여러 파일을 하나의 파일로 이동할 수 없습니다

$ mv *
mv: target `c' is not a directory

하위 디렉터리를 추가해 보겠습니다.

$ mkdir d

할 수 있는여러 파일을 하위 디렉터리로 이동

$ mv *
$ ls
d
$ ls d
a  b  c

관련 정보