Linux에서 () 및 공백과 같은 특수 문자를 사용하여 파일 이름을 지속적으로 만드는 방법은 무엇입니까? [폐쇄]

Linux에서 () 및 공백과 같은 특수 문자를 사용하여 파일 이름을 지속적으로 만드는 방법은 무엇입니까? [폐쇄]

을 사용하여 많은 파일을 만들려고 합니다 C. 난 끝냈어 mkdir -p directory && touch directory/filename. 내 루프가 이름에 특수 문자가 포함된 파일에 도달하면 오류가 발생합니다.

syntax error :" unexpected "("

도와주세요?

답변1

귀하의 문제 system()system(). 이는 또한 결과 쉘이 자체 구문을 사용하여 전체 명령을 평가하므로 쉘이 특별히 처리하는 문자를 이스케이프해야 함을 의미합니다.

C에서 파일과 디렉터리를 생성하는 보다 강력하고 오류가 덜 발생하는 방법은 이 작업을 위해 제공되는 실제 C 함수, 즉 mkdir()open()/ 를 사용하는 것입니다 creat().

#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>

int
main(void)
{
  char dir[] = "some(directory)with*special[characters]";
  char file[] = "some(file)with*the[same]characters";
  int fd;

  if (mkdir(dir, 0755) == -1)
    err(EXIT_FAILURE, "creating directory failed");
  if ((fd = open(file, O_WRONLY|O_CREAT|O_TRUNC, 0644)) == -1)
    err(EXIT_FAILURE, "creating file failed");
  close(fd);

  /* ... */

  return 0;
}

답변2

다음과 같이 파일 경로를 따옴표로 묶습니다.

touch "directory/file"

답변3

파일 이름을 "인용"해야 합니다.

touch "directory/file with whitespace (and special characters)"

인용문과 특수문자에 대해서는 bash 매뉴얼을 읽어보세요.

답변4

system()매개변수가 포함된 쉘 명령을 호출하기 위해 inside를 사용하는 경우 C이러한 매개변수를 인용하지 않도록 환경을 사용하여 매개변수를 전달하는 것이 가장 좋습니다.

파일 경로(문자 포함)는 다음 위치에 저장됩니다 file_path.

if (setenv("FILE", file_path, 1) < 0) {
  perror("setenv");
  exit(1);
}
system("mkdir -p -- \"$(dirname -- \"$FILE\")\" && touch -- \"$FILE\"");

이렇게 하면 (내부에서 호출된) 고정 문자열을 전달할 수 sh -c있으며 쉘 코드가 정확하다면(위의 인용문 참고) system()임의 코드 주입 취약점에 대해 걱정할 필요가 없습니다.--

sh(위의 내용 에는 모든 후행 줄 바꿈이 제거되는 일반적인 명령 대체 문제가 있으므로 file_path유사한 상황에서는 실패 합니다 foo/bar\n/file. 이에 대해 작업할지 여부는 귀하가 결정하도록 하겠습니다).

쉘 코드의 파일 이름을 전달하려는 system()경우아니요하다:

sprintf(cmd, "mkdir -p -- \"%s\" && touch -- \"%s\"", dir_path, file_path);

이는 여전히 명령 주입 취약점이기 때문입니다(예: 파일 이름은 $(reboot)또는 와 같습니다 ";reboot;:". 큰따옴표 대신 작은따옴표를 사용하는 경우에도 마찬가지입니다.

다음을 수행해야 합니다.

sprintf(cmd, "mkdir -p -- %s && touch -- %s",
  shquote(dir_path), shquote(file_path));

각 문자를 작은따옴표 로 바꾸고 결과를 묶는 shquote()함수(구현은 연습으로 남음)는 어디에 있습니까? 따라서 예를 들어 return for (참조된 파일은 최대 4 * 길이 + 2가 될 수 있으므로 버퍼에 공간을 할당할 때 이를 고려해야 함 ).''\'''foo'\''bar'foo'barcmd

이것이 가장 안전한 참조 방법입니다. 큰따옴표나 백슬래시를 사용하는 인용 방법은 외부 문자 집합을 사용하는 일부 로케일에서 문제가 되어 잠재적으로 임의 코드 삽입 취약점을 초래할 수 있습니다.

관련 정보