#bash
#bash
Вопрос:
Я дергаю себя за волосы над этим в течение нескольких дней.. очень раздражает..
Я знаю, что это как-то связано с utf-8 и string, не выводящими правильный формат, но не могу понять, какой..
Это код:
#!/bin/bash
#test
REGURL=http://bugs.ws
CHECKURL=$(curl -m 3 -sk --head "$REGURL" | grep -i "location" | awk '{print $2}')
if [[ "${CHECKURL: -1}" != *'/'* ]] # if redirected url does not contain / at end, we need to add it
then
CHECKURL ='/'
echo "$CHECKURL"
fi
Это выполняет некоторую замену символов, а не просто добавляет ‘/’ после URL..
это работает, когда вы делаете это без конвейерного curl, grep, поэтому я знаю, что это что-то, связанное с grep или curl..
В принципе, результат ДОЛЖЕН иметь косую черту в конце, например: http://bugs.ws в конечном итоге произойдет перенаправление местоположения https://alphaterminte.com но мне нужно добавить ‘/’ в конец «alphatermite.com «Я все это перепробовал, я просто не могу поставить косую черту после переменной result.. он продолжает заменять ее первым символом обработанного результата.. Тьфу (да, этот тестовый код должен быть в bash)
Комментарии:
1.
[[ "${CHECKURL: -1}" != '/' ]]
было бы достаточно. Сcurl
могут возникнуть странности из-заcurl
возврата выходных данных с окончаниями строк DOS, например,"rn"
и многие утилиты Unix не очень хорошо справляются с ними. И вы можете быть совершенно правы в том, что еслиCHECKURL
содержит символы и в Юникоде — все ставки отменяются. UTF-8 также может быть проблематичным, но далеко не таким проблематичным, как Unicode. (особенно если в URL-адрес встроен символ глифа.) Здесь"Location: https://alphatermite.comtf-8"
возвращается,curl
что, по-видимому,'r'
приводит к перекрытию двух строк.
Ответ №1:
В выводе из curl
используются терминаторы возврата каретки перевода строки; инструменты unix ожидают только перевода строки и обрабатывают возврат каретки как часть содержимого строки. Конечный результат: CHECKURL
имеет в конце обычно не видимый символ возврата каретки, который все запутывает.
В частности, CHECKURL
в конечном итоге будет содержаться « https://alphatermite.com<carriage return>/
«, который выводит что-то вроде:
https://alphatermite.com
/
…за исключением того, что между ними только возврат каретки (без перевода строки), «/» печатается поверх «h» в «https».
Решение: вы могли бы добавить | tr -d 'r'
к созданию конвейера CHECKURL
, но мне просто пришлось бы awk
делать все за один шаг:
CHECKURL=$(curl -m 3 -sk --head "$REGURL" | awk '/^[Ll]ocation:/ {sub("r", "", $2); print $2}')
Объяснение: /^[Ll]ocation:/"
часть позволяет печатать только заголовок Location (или «местоположение») и sub("r", "", $2)
удаляет возврат каретки из $2
перед его печатью.
Кстати, я бы использовал это для проверки наличия «/» в конце строки:
if [[ "${CHECKURL}" != *'/' ]]
Вы можете либо извлечь последний символ и посмотреть, является ли он «/», либо использовать шаблон подстановки, чтобы проверить, заканчивается ли он на «/»; нет необходимости делать и то, и другое.
КСТАТИ, я также рекомендую использовать имена переменных в нижнем или смешанном регистре, чтобы избежать случайного использования одного из многих имен с заглавными буквами, которые имеют особое значение (и, следовательно, неожиданные последствия).
Комментарии:
1. Ты, мой друг, настоящий мужчина. Это была именно проблема, замена » r» устраняет ее!!!
2. @RavinderSingh13: да, спасибо, что напомнили мне, я думал, что из-за того, что у меня недостаточно репутации, я не смогу нажать на кнопку.
3. «КСТАТИ, я также рекомендую использовать имена переменных в нижнем или смешанном регистре, чтобы избежать случайного использования одного из многих имен с заглавными буквами, которые имеют особое значение (и, следовательно, неожиданные последствия)». Хм .. Прочитав все имеющиеся у меня руководства по bash, я подумал, что они рекомендуют использовать caps, чтобы не путать их с обычными функциями или просто знать, что они являются переменными, может быть, добавив «_» впереди, например _CHECKURL =$ (etc) ?
4. @Gordon Davisson: Как вам удалось быстро увидеть возврат каретки с помощью этой команды curl grep? Я просто спрашиваю на будущее, есть ли программа, которая выводит все в определенном формате, который показывает все? Спасибо.
5. Моя ошибка. Хороший улов.
CHECKURL=$(curl -m 3 -sk --head "$REGURL" | awk '/^Location/{sub("r","",$2); print match($2,//$/) ? $2 : $2"/"}')
это сработало бы и для теста.
Ответ №2:
Попробуйте регулярное выражение bash
url=http://bugs.ws
re='.*/$'
[[ $url =~ $re ]] || url ='/'