(git) Bash: чем именно разрыв строки отличается от \n в переменной?
Мои извинения, я, должно быть, допустил некоторые ошибки при выполнении первоначальных тестов, так как после объединения всего в один скрипт вывод xxd действительно всегда соответствует вводу stdouput.
Полный сценарий находится здесь: https://pastebin.pl/view/454913ec. Я обновляю свой вопрос и оставляю исходный (но неправильный) вопрос ниже.
Вывод сценария, который я получаю, следующий:
$ ./test.sh
# Case 1A: echo -n $TEST1
hello world
00000000: 6865 6c6c 6f20 776f 726c 64 hello world
# Case 1B: echo -n -e $TEST1
hello world
00000000: 6865 6c6c 6f20 776f 726c 64 hello world
# Case 1C: echo -n "$TEST1"
hello
world
00000000: 6865 6c6c 6f0a 776f 726c 64 hello.world
# Case 1D: echo -n -e "$TEST1"
hello
world
00000000: 6865 6c6c 6f0a 776f 726c 64 hello.world
# Case 1E: printf "%s" $TEST1
helloworld
00000000: 6865 6c6c 6f77 6f72 6c64 helloworld
# Case 1F: $ printf "%s" "$TEST1"
hello
world
00000000: 6865 6c6c 6f0a 776f 726c 64 hello.world
# --------------------------------
# Case 2A: $ echo -n $TEST2
hello\nworld
00000000: 6865 6c6c 6f5c 6e77 6f72 6c64 hello\nworld
# Case 2B: echo -n -e $TEST2
hello
world
00000000: 6865 6c6c 6f0a 776f 726c 64 hello.world
# Case 2C: echo -n "$TEST2"
hello\nworld
00000000: 6865 6c6c 6f5c 6e77 6f72 6c64 hello\nworld
# Case 2D: echo -n -e "$TEST2"
hello
world
00000000: 6865 6c6c 6f0a 776f 726c 64 hello.world
# Case 2E: printf "%s" $TEST2
hello\nworld
00000000: 6865 6c6c 6f5c 6e77 6f72 6c64 hello\nworld
# Case 2F: printf "%s" "$TEST2"
hello\nworld
00000000: 6865 6c6c 6f5c 6e77 6f72 6c64 hello\nworld
Таким образом, вывод xxd, по крайней мере, одинаков для того же вывода стандартного вывода. Еще раз извините за это!
Итак, оставшиеся у меня вопросы:
Почему результат на выходе
helloworld
Какие последовательности байтов ДЕЙСТВИТЕЛЬНО содержатся в TEST1 и TEST2, и какой способ это выяснить?
Как я могу заставить printf интерпретировать тип новой строки, закодированный в TEST2?
является ли следующее присваивание переносимым (в том смысле, что оно всегда будет приводить к одному и тому же двоичному содержимому переменных?
$ TEST1="привет
мир" $ TEST2="привет\nмир"
в другом вопросе я прочитал, что локаль применяется только во время расширения, так что это должно означать, что так и должно быть, верно?
Оригинальный (но неправильный) вопрос:
Я выполнил следующие тесты, используя git bash:
$ TEST1="hello
> world"
$ TEST2="hello\nworld"
# Case 1A:
$ echo -n $TEST1
hello world
$ echo -n $TEST1 | xxd
00000000: 6865 6c6c 6f20 776f 726c 64 hello world
# Case 1B:
$ echo -n -e $TEST1
hello world
$ echo -n -e $TEST1 | xxd
00000000: 6865 6c6c 6f20 776f 726c 64 hello world
# Case 1C:
$ echo -n "$TEST1"
hello
world
$ echo -n "$TEST1" | xxd
00000000: 6865 6c6c 6f0a 776f 726c 64 hello.world
# Case 1D:
$ echo -n -e "$TEST1"
hello
world
$ echo -n -e "$TEST1" | xxd
00000000: 6865 6c6c 6f0a 776f 726c 64 hello.world
# Case 1E:
$ printf "%s" $TEST1
helloworld
$ printf "%s" $TEST1 | xxd
00000000: 6865 6c6c 6f77 6f72 6c64 helloworld
# Case 1F:
$ printf "%s" "$TEST1"
hello
world
$ printf "%s" "$TEST1" | xxd
00000000: 6865 6c6c 6f0a 776f 726c 64 hello.world
$
# --------------------------------
# Case 2A:
$ echo -n $TEST2
hello\nworld
$ echo -n $TEST2 | xxd
00000000: 6865 6c6c 6f20 776f 726c 64 hello world
# Case 2B:
$ echo -n -e $TEST2
hello
world
$ echo -n -e $TEST2 | xxd
00000000: 6865 6c6c 6f20 776f 726c 64 hello world
# Case 2C:
$ echo -n "$TEST2"
hello\nworld
$ echo -n "$TEST2" | xxd
00000000: 6865 6c6c 6f0a 776f 726c 64 hello.world
# Case 2D:
$ echo -n -e "$TEST2"
hello
world
$ echo -n -e "$TEST2" | xxd
00000000: 6865 6c6c 6f0a 776f 726c 64 hello.world
# Case 2E:
$ printf "%s" $TEST2
hello\nworld
$ printf "%s" $TEST2 | xxd
00000000: 6865 6c6c 6f77 6f72 6c64 helloworld
# Case 2F:
$ printf "%s" "$TEST2"
hello\nworld
$ printf "%s" "$TEST2" | xxd
00000000: 6865 6c6c 6f0a 776f 726c 64 hello.world
$
во-первых: меня это расстраивает. Также мне хотелось бы добавить несколько собственных цветов в кодовые блоки в stackoverflow, чтобы лучше визуализировать проблему (например, раскрасить одинаковые выходные данные в одинаковые цвета).
второй: учитывая это, может ли кто-нибудь помочь мне разобраться в этих результатах, объяснив базовые правила, которые влияют на эти результаты?
Итак, некоторые вещи, которые меня смущают, например:
Несмотря на то, что напечатанные выходные данные стандартного вывода различаются для и (например,
Case 1A
приводит к получению другого результата, чемcase 2A
), кажется, что фактические байты, которые xxd получает в качестве входных данных, идентичны во всех соответствующих случаях (я имею в виду все соответствующие случаиCase 1x
всегда имеет тот же вывод xxd, что иCase 2x
, даже если соответствующие выходные данные стандартного вывода одной и той же команды не равны). Как это возможно?Очевидно, что содержимое и должно каким-то образом отличаться, иначе было бы невозможно, чтобы их отображение/печать могли привести к различным выводам стандартного вывода. Итак, как я могу правильно вывести ДЕЙСТВИТЕЛЬНЫЕ биты (в шестнадцатеричном формате или в каком-то другом виде, не имеет значения, если это четкое представление фактического содержимого переменной), содержащиеся в этих переменных?
случаи будут указывать на то, что xxd получает символ новой строки ascii именно тогда, когда в распечатке также отображается разрыв строки. Однако в случаях
Case 2B
печатает разрыв строки, но не приводит к появлению символа иCase 2F
не печатает перенос строки, однако приводит к0A
характер
Я понимаю, что разрыв строки в переменных and закодирован по-разному, и что при повторении двойных кавычек кажется, что расширяется (это правильная терминология?) тип разрыва строки, содержащийся вTEST1
, хотя флаг -e для echo, похоже, интерпретирует тип разрыва строки, закодированный в , но это не объясняет выходные данные xxd, а также случаи printf.
Почему
Case 1E
результат в$ printf "%s" $TEST1 helloworld
Как заставить printf применять разрывы строк, закодированные в
TEST2
переменная?Какой урок здесь следует извлечь наиболее важным?
примечания: я воздержался от добавления
$ TEST3="hello\n
world"
чтобы вопрос был кратким.
Я также тестировал использование одинарных кавычек ' ' вместо двойных кавычек " " при определении переменных, что, похоже, не влияет на результаты.
1 ответ
Я не уверен, что этим объясняются все различия, но я считаю, что разница в том, что TEST1 содержит возврат каретки(), а не перевод строки().
Кроме того, этот возврат каретки является частью строки как двоичный символ и не требует никакой интерпретации.
Вы можете увидеть различия по следующему коду:
$ echo $TEST1 | od -w32 -t x1c
0000000 68 65 6c 6c 6f 20 3e 20 77 6f 72 6c 64 0a
h e l l o > w o r l d \n
$ echo $TEST2 | od -w32 -t x1c
0000000 68 65 6c 6c 6f 5c 6e 77 6f 72 6c 64 0a
h e l l o \ n w o r l d \n
Следует также помнить, что