Как я могу проверить, какие части POSIX использует приложение?

Я заставил это работать с некоторыми изменениями:

#!/bin/bash

set -o nounset
# set -o errexit
# trap 'echo "Aborting due to errexit on line $LINENO. Exit code: $?" >&2' ERR
set -o errtrace
set -o pipefail

SCR="bunny"
SCRIPT="/home/../run.sh" 

function main() {
    if find_screen $SCR >/dev/null; then
        close_screen
        start_script
    fi
}

function start_script {
    echo "Starting script with new screen"
    screen -d -m -S $SCR sh $SCRIPT
}

function close_screen {
    if find_screen $SCR >/dev/null; then
        echo "Found! Deleting $SCR"
        screen -S $target_screen -X quit
    fi
}

function find_screen {

    result=$(screen -ls "$1" | grep -o "^\s*[0-9]*\.$1[ "$'\t'"](" --color=NEVER -m 1 | grep -oh "[0-9]*\.$1" --color=NEVER -m 1)

    if [ -z $result ]; then
      echo "$1"
      return 1
    else
        echo $result
        return 0
    fi
}
target_screen=$(find_screen $SCR)
main "$@"

  • Я закомментировал следующие две строки:
       set -o errexit  
       trap 'echo "Aborting due to errexit on line $LINENO. Exit code: $?" >&2' ERR  

Эти строки мешали вашему оператору return 1 в функции find_screen

  • В функции close_screen screen -S -X $ target_screen quit потребовалась небольшая модификация: screen -S $ target_screen -X quit для соответствия переключателям с соответствующие параметры.

Оператор if в функции find_screen никогда не возвращал значение true, поэтому я немного обновил его, добавив переменную results , присвоив ее исходному тесту. состояние. Итоговое обновление выглядит следующим образом:

    result=$(screen -ls "$1" | grep -o "^\s*[0-9]*\.$1[ "$'\t'"](" --color=NEVER -m 1 | grep -oh "[0-9]*\.$1" --color=NEVER -m 1)

    if [ -z $result ]; then
      echo "$1"
      return 1
    else
        echo $result
        return 0
    fi

Другие элементы

  • Если вы хотите назвать свой экран на основе переменной $ SCR, вам необходимо использовать переключатель -S , как на экране

-d -m -S $ SCR

... и добавить любые другие параметры и переключатели по желанию.

  • В функции start_script похоже, что вы пытаетесь использовать переключатель -t вместо -S на экране
    - d -m -t $ SCR sh $ SCRIPT - в соответствии с вашим описанием « создать новый сеанс экрана с именем SCRIPT » вы должны использовать -S для настройки экрана имя сеанса. Вы можете объединить это с -t , чтобы задать имя окна, поскольку в сеансе экрана может быть несколько окон: screen -d -m -S $ SCR -t WindowName1
]
1
09.09.2018, 22:22
2 ответа

strace отслеживает системные вызовы. POSIX включает как системные вызовы, так и функции . Некоторые платформы поддерживают аналогичный ltrace (вызовы библиотеки трассировки ).

Например, утилита командной строки date с ltrace будет показывать что-то вроде этого:

__libc_start_main(0x401a50, 1, 0x7ffe41310418, 0x40a100, 0x40a0f0 <unfinished ...>
strrchr("date", '/')                             = NULL
setlocale(6, "")                                 = "en_US.UTF-8"
bindtextdomain("coreutils", "/usr/share/locale") = "/usr/share/locale"
textdomain("coreutils")                          = "coreutils"
__cxa_atexit(0x402b60, 0, 0, 0x736c6974756572, 0x7f8c29d9bea8) = 0
getenv("POSIXLY_CORRECT")                        = NULL
nl_langinfo(131180, 0x40b6b9, 0, 0, 0)           = 0x7f8c23e98955
clock_gettime(0, 0x7ffe41310260, 0x20ef440, 0, 0) = 0
localtime(0x7ffe413101d0)                        = 0x7f8c29d9f380
strftime("", 140239874654731, NULL, 0x7ffe4130fd63) = 4
fwrite("Mon", 3, 1, 0x7f8c29d9a7a0)              = 1
fputc(' ', 0x7f8c29d9a7a0)                       = 32
strftime("", 140239874654844, NULL, 0x7ffe4130fd63) = 4
fwrite("Sep", 3, 1, 0x7f8c29d9a7a0)              = 1
fputc(' ', 0x7f8c29d9a7a0)                       = 32
fwrite("12\004\200\0011A\376\177", 2, 1, 0x7f8c29d9a7a0) = 1
fputc(' ', 0x7f8c29d9a7a0)                       = 32
fwrite("17\004\200\0011A\376\177", 2, 1, 0x7f8c29d9a7a0) = 1
fputc(':', 0x7f8c29d9a7a0)                       = 58
fwrite("43\004\200\0011A\376\177", 2, 1, 0x7f8c29d9a7a0) = 1
fputc(':', 0x7f8c29d9a7a0)                       = 58
fwrite("52\004\200\0011A\376\177", 2, 1, 0x7f8c29d9a7a0) = 1
fputc(' ', 0x7f8c29d9a7a0)                       = 32
strlen("EDT")                                    = 3
fwrite("EDT", 3, 1, 0x7f8c29d9a7a0)              = 1
fputc(' ', 0x7f8c29d9a7a0)                       = 32
fwrite("2016\004\200\0011A\376\177", 4, 1, 0x7f8c29d9a7a0) = 1
__overflow(0x7f8c29d9a7a0, 10, 4, 54, 0x7f8c2a1c401c) = 10
exit(0 <unfinished ...>
...

, а strace показывает нечто иное:

execve("/bin/date", ["date"], [/* 60 vars */]) = 0
brk(0)                                  = 0x1ac9000
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7ff3eed91000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY)      = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=132177, ...}) = 0
mmap(NULL, 132177, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7ff3eed70000
close(3)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/x86_64-linux-gnu/librt.so.1", O_RDONLY) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\220!\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0644, st_size=31744, ...}) = 0
mmap(NULL, 2128856, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7ff3ee96c000
mprotect(0x7ff3ee973000, 2093056, PROT_NONE) = 0
mmap(0x7ff3eeb72000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x6000) = 0x7ff3eeb72000
close(3)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\300\357\1\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1607696, ...}) = 0
mmap(NULL, 3721272, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7ff3ee5df000
mprotect(0x7ff3ee763000, 2093056, PROT_NONE) = 0
mmap(0x7ff3ee962000, 20480, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x183000) = 0x7ff3ee962000
mmap(0x7ff3ee967000, 18488, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7ff3ee967000
close(3)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/x86_64-linux-gnu/libpthread.so.0", O_RDONLY) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0@\\\0\0\0\0\0\0"..., 832) = 832
...

Для обоих случаев я привел только образец. Но если вы сравните две полные трассы, вы не увидите большой корреляции между ними. Это не всегда верно: функции, выполняющие ввод-вывод, могут быть довольно точно сопоставлены между ними. Но только в самом конце журнала strace отображаются все операции ввода-вывода, которые могут быть сопоставлены с журналом ltrace . Все эти вызовы fwrite и fputc будут работать в памяти до тех пор, пока в конце не будет системного вызова write :

open("/usr/lib/locale/locale-archive", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=110939968, ...}) = 0
mmap(NULL, 110939968, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7ff3e79f6000
close(3)
open("/etc/localtime", O_RDONLY)        = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=3519, ...}) = 0
fstat(3, {st_mode=S_IFREG|0644, st_size=3519, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7ff3eed90000
read(3, "TZif2\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\4\0\0\0\4\0\0\0\0"..., 4096) = 3519
lseek(3, -2252, SEEK_CUR)               = 1267
read(3, "TZif2\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\5\0\0\0\5\0\0\0\0"..., 4096) = 2252
close(3)                                = 0
munmap(0x7ff3eed90000, 4096)            = 0
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 1), ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7ff3eed90000
write(1, "Mon Sep 12 17:43:41 EDT 2016\n", 29) = 29
close(1)                                = 0
munmap(0x7ff3eed90000, 4096)            = 0
close(2)                                = 0
exit_group(0)                           = ?

В обеих трассировках имена, начинающиеся с подчеркивания определенно не относятся к POSIX. Некоторые другие также зависят от реализации, например, вызов exit_group .

Если у вас нет исходного кода для приложения и вы можете наблюдать только двоичный файл, не существует надежного способа улучшить этот подход. POSIX основан на множестве функций, использующих исходный код приложения. Например, некоторые функции зависят от файлов системных заголовков, для которых скомпилировано приложение, в то время как другие функции зависят от поведения утилит командной строки.Сертификационные тесты POSIX используют наблюдаемое поведение приложения с учетом его исходного кода, используя стандартные интерфейсы. Внутренние детали могут отличаться, и это то, что вам показывает strace / ltrace, как отмечено в примере с exit_group .

Дополнительная литература:

0
27.01.2020, 23:25

Если вы можете скомпилировать и запустить код, и если вы увидите, какие системные вызовы он выполняет, будет достаточно (т. е. вы можете выполните все, что вам нужно знать), тогда

strace myapp

запустит myapp и перечислит все системные вызовы (POSIX и другие), которые он выполняет.

3
27.01.2020, 23:25

Теги

Похожие вопросы