Различные ошибки в подстановке команды $()

Я получаю разные ошибки при запуске кода ниже (он подсчитывает количество файлов .mp3 в каждом пользовательском каталоге):

    for us in /home/*
    do
            if [ -d $us ]
            then
                    LT=$(find $us -name "*.jpg" -o -name "*.mp4" -o -name "*.mp3")
    
                    N_MP3=$("$LT" | grep "\.mp3$" | wc -l)
                    N_MP3=$($LT | grep "\.mp3$" | wc -l)
                    N_MP3=$(find $us -name "*.jpg" -o -name "*.mp4" -o -name "*.mp3" | grep "\.mp3$" | wc -l)
            fi
    done

Учтите, что у нас есть в каком-то пользовательском каталоге, скажем, user=ubuntu, файлы:

  • образец.jpg
  • образец.mp3

Итак, запустим код:


(1) Выполнение "$LT" | ..., я получаю сообщение:

/home/ubuntu/Desktop/Songs/sample.mp3 /home/ubuntu/Desktop/Images/sample.jpg: Нет такого файла или каталога

что означает, что команда «$LT» была выполнена и обнаружила все файлы .mp4, .mp3 или .jpg в моем пользователе, а затем выдает эту ошибку.


(2) Выполнение $LT | ..., что эквивалентно $(find $us -name ".jpg" -o -name ".mp4" -o -name "*.mp3") | ... Я получаю сообщение /home/ubuntu/Desktop/Songs/sample.mp3: Отказано в доступе. Это означает, что команда $LT была выполнена и нашла только файл .mp3, а затем выдает эту ошибку.

Если я удалю sample.jpg из моего user=ubuntu, то в обоих случаях я получу одно и то же сообщение об ошибке: /home/ubuntu/Desktop/Songs/sample.mp3: Отказано в доступе.

Я знаю (но не знаю почему) я должен использовать команду echo перед $LT, но я хотел бы знать, что происходит в тех случаях, когда я раньше не использовал команду echo. Пожалуйста, может кто-нибудь пролить свет на эти ошибки?

LT не является определением функции; он содержит результат запуска find немедленно.
chepner 18.11.2022 22:26
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
1
54
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Это происходит из-за разделения слов.

При разделении слов первое слово становится именем команды, а остальные слова становятся аргументами.

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

Bash показывает имя команды, которую вы пытались выполнить, когда оно не найдено, поэтому значения отражаются в сообщении об ошибке:

$ var = "foo bar baz"

$ foo bar baz
-bash: foo: command not found
$ $var
-bash: foo: command not found

$ "foo bar baz"
-bash: foo bar baz: command not found
$ "$var"
-bash: foo bar baz: command not found
Ответ принят как подходящий

LT=$( ...)

Вы используете подстановку команд, поэтому вы не сохраняете строку для последующего повторного использования, вы пытаетесь выполнить вывод команды find; это не сработает.

Чуть более элегантно:

function lt() { find $1 -name "*.jpg" -o -name "*.mp4" -o -name "*.mp3"; }
for us in /home/*
do
   if [ -d "$us" ]; then
        N_MP3=$(lt "$us" | grep "\.mp3$" | wc -l)
   fi
done
$lt=... будучи неверным в сторону, первый подход имеет так много проблем, что его даже не стоит предлагать. Используйте функцию для того, для чего они предназначены.
chepner 18.11.2022 22:28

Другие вопросы по теме