Предполагая, что у вас установлен strace:
strace /path/to/binary
изменить :Я не читал последнюю часть, в которой говорилось, что у вас нет strace, вы должны иметь возможность скачать архив strace и собрать его без использования менеджера пакетов. Вы можете создать его статически на другом компьютере и скопировать, если у вас не установлены инструменты сборки.
Ваш исходный код до редактирования:
#!/bin/sh
_directory1="~/test1"
_directory2="test2"
for i in $(cd "${_directory1}/$_directory2")
do
echo "$i"
done
Тильда(~
)не ведет себя как переменная. Например, он не будет расширяться до пути к вашему домашнему каталогу при использовании в кавычках. В сценарии используйте $HOME
вместо тильды. ~
— это «ярлык», который вы можете использовать в командной строке, но $HOME
более информативен в сценарии.
cd
не выводит ничего, что можно было бы зациклить, поэтому использование cd
в замене команды на for
не принесет вам ничего хорошего. К сожалению, неясно, что вы хотите, чтобы ваш цикл на самом деле делал, поэтому я не могу дать вам надежную альтернативную реализацию.
Код с вашими правками:
#!/bin/sh
_directory1="/home/user/test1"
_directory2="test2"
cd "${_directory1}/$_directory2"
for i in *
do
echo "$i"
done
Этот код будет выводить только
"./myscript.sh: 6: cd: can't cd to /test2"
если вы ошиблись в имени переменной_directory1
(и переменная с ошибкой пуста, а каталог /test2
не существует ).
Затем вы снова отредактировали сообщение об ошибке , указав, что оно выводит
./myscript.sh: 6: cd: can't cd to /home/user/test1/test2
, что просто означает, что каталог /home/user/test1/test2
не существует. Вы не предоставили доказательств того, что этот каталог действительно существует, поэтому мы должны поверить на слово вашей системе.
Вот сценарий, который выводит список содержимого каталога (при условии, что каталог существует ). Код печатает полное имя каждого файла.
#!/bin/bash
topdir=$HOME/test1
subdir=test2
printf '%s\n' "$topdir/$subdir"/*
Или,
#!/bin/bash
topdir=$HOME/test1
subdir=test2
shopt -s nullglob
for name in "$topdir/$subdir"/*; do
printf '%s\n' "$name"
done
Параметр оболочки nullglob
запрещает запуск цикла вообще, если заданный шаблон ничему не соответствует. Без установки параметра nullglob
шаблон останется нерасширенным, если он не соответствует чему-либо, и цикл будет использовать его в качестве значения для $name
за одну итерацию.
Вы также можете установить параметр оболочки dotglob
(shopt -s dotglob
), если вас интересуют скрытые имена (имен файлов, начинающихся с .
символа ).
Или, не печатая полный путь к каждому имени файла,
#!/bin/bash
topdir=$HOME/test1
subdir=test2
cd "$topdir/$subdir" || exit 1
printf '%s\n' *
exit 1
прервет сценарий, если cd
выйдет из строя.
Или,
#!/bin/bash
topdir=$HOME/test1
subdir=test2
cd "$topdir/$subdir" || exit 1
shopt -s nullglob
for name in *; do
printf '%s\n' "$name"
done
Для печати только имен файлов без полного пути, без использованияcd
:
#!/bin/bash
topdir=$HOME/test1
subdir=test2
shopt -s nullglob
for name in "$topdir/$subdir"/*; do
printf '%s\n' "$( basename "$name" )"
# or: printf '%s\n' "${name##*/}"
done
При этом используется утилита basename
для извлечения только части имен файлов из путей. Альтернатива в комментарии использует стандартную подстановку параметров, ${name##*/}
, чтобы удалить начальный путь к каталогу перед именами файлов (буквально «удалить самую длинную строку префикса, соответствующую шаблону */
из $name
» ).