![쉘에서 라이브러리 명령을 실행하는 방법은 무엇입니까?](https://linux55.com/image/131093/%EC%89%98%EC%97%90%EC%84%9C%20%EB%9D%BC%EC%9D%B4%EB%B8%8C%EB%9F%AC%EB%A6%AC%20%EB%AA%85%EB%A0%B9%EC%9D%84%20%EC%8B%A4%ED%96%89%ED%95%98%EB%8A%94%20%EB%B0%A9%EB%B2%95%EC%9D%80%20%EB%AC%B4%EC%97%87%EC%9E%85%EB%8B%88%EA%B9%8C%3F.png)
간단히 문자열의 길이(즉, 해시 값)를 계산하고 싶습니다. 그래서 터미널을 열고 다음을 수행합니다.
$ apropos length
(3)
이렇게 하면 끝에 추가되거나 추가된 여러 명령/함수가 반환됩니다 . (3ssl)
지금남자 남자이러한 의미에 대한 정보를 제공하십시오 section numbers
.
3 Library calls (functions within program libraries)
호기심 때문에 방금 이 모든 명령을 시도했습니다(적어도 하나는 작동할 것입니다).
strcspn (3) - get length of a prefix substring
strlen (3) - calculate the length of a string
strnlen (3) - determine the length of a fixed-size string
strspn (3) - get length of a prefix substring
wcslen (3) - determine the length of a wide-character string
wcsnlen (3) - determine the length of a fixed-size wide-character string
모든 명령에서 동일한 오류가 발생함
$ strnlen HelloWorld
$ strnlen: command not found
응 알아쉘에서 문자열 길이를 찾는 방법wc -m
그리고 다른 해결 방법 expr length
.
그러나 여기에는 두 가지 질문이 있습니다.
- 사용하는 방법어느
library calls (3)
껍질 안에? - 다른 명령 없이 라이브러리 호출만 사용하여 문자열 길이를 계산하는 방법은 무엇입니까?
참고: 질문은 일반적인 경우 library calls
와 셸에서의 사용법에 중점을 둡니다. 이는 첫 번째 질문에 대한 답변을 더욱 중요하게 만듭니다.
답변1
당신은 할 수있다해서는 안 된다할 수 있는 대로 하십시오.코살로난다의 답변현재 작업에 더 적합하고 문제를 설명합니다. 구체적으로 어떻게 사용하는지 물어보셨기 때문에어느하지만 터미널 내부에서 라이브러리를 호출하는 방법은 여러 가지가 있습니다...
이것Tiny C 컴파일러( tcc
) 지원 -run
플래그이는 작은 프로그램을 작성하여 C 코드를 (실제로) 해석할 수 있게 해줍니다.할 수 있는터미널 내의 모든 라이브러리 호출은 단일 호출로 사용할 수 있습니다.
strnlen
다음과 같이 함수를 실행할 수 있습니다 .
$ tcc -run <(echo '#include <stdio.h>'; echo '#include <string.h>'; echo 'void main(int argc, char **argv) {printf("%i\n", strnlen(argv[1], 1024));}') "Hello world"
11
이는 다음을 사용합니다.프로세스 교체다른 옵션이 있는 모든 결과를 포함하는 것으로 보이는 Bash, zsh 및 기타 쉘에서 tcc
읽을 파일을 제공하십시오.echo
이를 생성하는 함수를 만들 수 있습니다.
call_library_function_s_i() {
func=$1
shift
tcc -run <(echo '#include <stdio.h>'; echo '#include <string.h>'; echo 'void main(int argc, char **argv) {printf("%i\n", '$func'(argv[1]));}') "$*"
}
$ call_library_function_s_i strlen hello world
(여기서는 단항 함수 string->int를 사용하고 있습니다 strlen
. 각각의 수량과 반환 유형에 대해 별도의 함수가 필요합니다).
또 다른 옵션은배쉬 ctypes.sh
플러그인Tavis Ormandy가 작성 dlopen
했으며 dlsym
. 예를 들어 다음을 사용할 수 있습니다.
$ dlcall -r uint64 strlen "hello world"
예상대로 함수를 호출합니다.
이는 "터미널에서" 이 작업을 수행하는 가장 직접적인 방법이지만 배포판에 패키지로 포함되어 있지 않을 가능성이 높으므로 수동으로 설치해야 합니다(중요). 여기 몇 가지 정보가 있습니다ctypes.sh
자사 홈페이지 에서 인용사람들이 이것에 대해 어떻게 느끼는지에 대한 전반적인 인상을 주십시오.
- “정말 역겹다”
- '이건 멈춰야 해'
- "너무 멀리 가셨네요"
다른 쉘에도 비슷한 도구가 있을 수 있지만 이에 대해 잘 모르겠습니다. 이론적으로는 간단한 경우에 정확히 이 작업을 수행하는 독립 실행형 명령이 있어서는 안 될 이유가 없지만 아직 찾지 못했다는 사실에 조금 놀랐습니다.
...그래서 하나 만들었어요! dlcall
명령줄에서 라이브러리 함수를 호출할 수 있습니다.:
$ dlcall strnlen "hello world" 6
$ dlcall sin 2.5
$ dlcall strchr "hello world" -c ' '
제한된 기능 프로토타입 세트를 지원하며 아직 안정성이나 탄력성이 떨어지지만 현재로서는 존재합니다.
예를 들어 다음을 사용할 수도 있습니다.파이썬과python -c 'import ctypes; import sys; print(ctypes.cdll.LoadLibrary("libc.so.6").strlen(" ".join(sys.argv[1:])))' hello world
, 그러나 이것은 확실히 가장 쉬운 방법은 아닙니다. Perl, Ruby 및 기타 언어에는 유사한 기능을 사용할 수 있습니다.
따라서 귀하의 질문에 대한 답변은 다음과 같습니다.
- 위의 방법 중 하나를 사용하십시오.
- 너하다라이브러리로 부팅하려면 또 다른 명령이 필요하거나 셸에 연결되는 소프트웨어가 필요합니다.
대체로 이 작업을 다른 방식으로 수행하는 것이 거의 확실히 더 좋습니다.
답변2
이 apropos
명령은 여러 면에서 유용하지만 많은 "정크"를 제공하기도 합니다. 당신이 나열한 것의 대부분은 C 라이브러리 루틴(매뉴얼의 섹션 3에 관한 것입니다)이며 쉘에서 직접 사용할 수 없습니다.
이를 사용하려면 이를 호출하는 C 프로그램을 작성해야 합니다. 이는 이 특정 사이트(다음 위치에 있음)에서 다루는 주제의 범위를 벗어납니다.스택 오버플로).
귀하의 질문에 대한 답변은 다음과 같습니다.
- 그럴 수 없습니다. C 라이브러리 루틴입니다.
- C 프로그램을 작성하지 않으면 할 수 없습니다.
나는 당신이 이것을 알고 있다는 것을 알고 있지만 완전성을 위해 셸에서 변수에 문자열이 있으면 다음 string
을 수행할 수 있습니다.
string='hello world'
printf 'Length of string "%s" is %d\n' "$string" "${#string}"
Length of string "hello world" is 11
11
그러면 소스가 ${#string}
의 문자열 길이로 확장되어 터미널에 인쇄됩니다 $string
.
내부적으로 쉘은 길이 계산을 수행하기 위해 나열된 라이브러리 호출 중 하나를 사용하고 있을 가능성이 높습니다.
이는 쉘 변수에 저장된 문자열의 길이를 얻는 쉘에서 가장 효율적인 방법입니다.
또한 참고 ${#string}
하세요POSIX 쉘 매개변수 확장, 따라서 어느 정도 POSIX 준수를 주장하는 모든 쉘 간에 이식 가능합니다.
답변3
나는 단지 그것을 하기 위해서 이것을 하지 않을 것이지만 strlen()
때로는 C 코드를 시험해 볼 때 유용한 트릭이 될 수도 있습니다.
사용자@호스트:~$ gdb gdb (gdb) 시작 임시 중단점 1,...main() (gdb) strlen("foobar")을 인쇄합니다. 1달러 = 6
이는 gdb
GNU 디버거이며 일반적으로 디버깅을 위한 프로그램 이름이 뒤에 옵니다. 우리에게는 그런 것이 없기 때문에 이 예제에서는 디버깅 자체를 맡깁니다. 그런 다음 프로그램이 start
시작되고 gdb
임의의 C 코드를 실행하는 데 사용할 수 있습니다.
답변4
공유 라이브러리의 함수를 대화형으로 호출하는 데 사용할 수 있는 도구: "Witchcraft Compiler Collection".https://github.com/endrazine/wcc
GitHub 페이지에서:
wsh: 부두 껍질
마법사 셸은 ELF 공유 라이브러리, ELF ET_DYN 실행 파일 및 Punk-C로 작성된 마법사 셸 스크립트를 입력으로 받아들입니다. 모든 실행 파일을 자체 주소 공간에 로드하고 API를 내장된 인터프리터에서 프로그래밍할 수 있도록 합니다. 이는 Java와 같은 언어의 리플렉션이 제공하는 것과 유사한 바이너리 기능을 제공합니다.
wsh의 사용 예 다음 명령은
/usr/sbin/apache2
wsh에서 실행 파일을 로드하고,ap_get_server_banner()
Apache에서 함수를 호출하여 배너를 검색하고, 이를wsh
인터프리터에 표시합니다.
jonathan@blackbox:~$ wsh /usr/sbin/apache2
> a = ap_get_server_banner()
> print(a)
Apache/2.4.7