Вставка нового события в календарь CalDAV с помощью curl

Я знаю, как использовать curl для вставки новых событий в календарь CalDAV, если событие сохранено как локальный файл ics предыдущей командой:

$command > $localfile
curl -T "$localfile" $url

Это отлично работает, но я хотел бы сделать это без необходимости в локальном файле, я хочу передать результат из команды $ в curl, что-то вроде этого:

$command | curl -T - $url

Согласно руководству curl, опция "T -" должна быть именно такой, какой требуется: предполагается чтение из стандартного ввода, а не из файла. Но если я использую эту опцию, я получаю этот ответ:

<?xml version="1.0" encoding="utf-8"?>
    <d:error xmlns:d="DAV:" xmlns:s="http://sabredav.org/ns">
      <s:exception>Sabre\DAV\Exception\Conflict</s:exception>
      <s:message>PUT is not allowed on non-files.</s:message>
    </d:error>

Я пробовал разные другие параметры, такие как "--data" и "--data-raw", но я еще не нашел правильную комбинацию. Может ли кто-нибудь помочь мне с этим, пожалуйста?


На самом деле полный командный цикл, который я пытаюсь реализовать, выглядит так:

cat<<EOC | curl -T - $url 
BEGIN:VCALENDAR
VERSION:2.0

BEGIN:VEVENT
CREATED:${CREATED}
UID:${RNDUID}
CLASS:PUBLIC
CATEGORIES:TV
SUMMARY:${SUMMARY}
LOCATION:${LOCATION}
DTSTART:${DTSTART}
DTEND:${DTEND}
DESCRIPTION:${DESCRIPTION}
END:VEVENT

END:VCALENDAR
EOC

Я попробовал «эхо» вместо «кошка», но это не меняет результат.


person weka    schedule 30.01.2020    source источник
comment
Разве вам не нужно echo эту команду? Поэтому echo $command | curl -T - $url   -  person Victor Deleau    schedule 30.01.2020
comment
Также может случиться так, что ваш тип содержимого HTTP по умолчанию не является файлом. Поэтому, возможно, вам нужно указать -H "Content-Type: text/plain" с правильным типом контента.   -  person Victor Deleau    schedule 30.01.2020
comment
Кажется, есть очень большая разница между обработкой этих двух команд: create_tempfile; curl -T $tempfile $url и create_tempfile; $tempfile кот | завиток -T - $url. В то время как первый работает отлично, второй завершается с помощью put, не разрешенного для не-файлов. Итак, я думаю, главный вопрос: как заставить NextCloud поверить, что вход — это файл и ничего больше?   -  person weka    schedule 01.02.2020
comment
Пожалуйста, отметьте ответ как принятый вместо того, чтобы писать «Решено» в заголовке.   -  person Dharman    schedule 02.02.2020


Ответы (1)


Эврика! :)

Решение состоит в том, чтобы использовать ЗДЕСЬ документ:

$CURL $url -T /dev/stdin <<-EOF
        BEGIN:VCALENDAR
        VERSION:2.0
        BEGIN:VEVENT
        CREATED:$CREATED
        UID:$RNDUID
        SUMMARY:$SUMMARY
        LOCATION:$LOCATION
        DTSTART:$DTSTART
        DTSTAMP:$DTSTART
        DTEND:$DTEND
        DESCRIPTION:$DESCRIPTION
        END:VEVENT
        END:VCALENDAR
EOF

Обратите внимание на входной параметр "/dev/stdin"! Параметр curl "-T" там не работает, когда для ввода используется "-" (тире). Вместо этого вы должны использовать "/dev/stdin", который, к сожалению, доступен не во всех Unix-подобных системах. В Linux его можно использовать в качестве замены "-", когда программы не поддерживают параметр "-" или если тире имеет для них другое значение, например, отмечает конец всех входных параметров.

"-" после "<<" является частью команды HERE document: она подавляет табуляторы, но не пробелы, поэтому документ можно упорядочить в более удобном для глаз виде.

я так и не понял в чем разница

cat<<EOF | curl ...
...
EOF

и решение, которое я нашел сейчас, кроме этой первой попытки, явно является бесполезным использованием cat. Но очень похоже, что «кошка» приносит что-то, что не очень нравится старой собаке по кличке «керл». ;)

Если у кого-то есть объяснение этому, я был бы очень благодарен здесь.

person weka    schedule 02.02.2020
comment
Рад, что вы нашли ответ! Я бы порекомендовал вам отредактировать заголовок вашего вопроса, чтобы сделать его более связанным с проблемой (как передать текст в команду CURL PUT или что-то в этом роде), теперь, когда вы лучше понимаете, что вызвало проблему. Кроме того, вместо того, чтобы включать РЕШЕНО в заголовок, просто отметьте свой ответ как правильный (рядом с вашим вопросом на SO будет отображаться зеленая отметка) - person Victor Deleau; 02.02.2020
comment
Я отметил ответ как принятый. Но я не уверен в названии, потому что не знаю, подходит ли это решение для передачи других данных, кроме календаря, в команду curl put. Я сомневаюсь, что использование документа ЗДЕСЬ будет работать с двоичными данными, такими как изображение. - person weka; 03.02.2020