LINUX.ORG.RU

В чём идея Golang и UNIX-овых бинарников в целом?

 , ,


0

2

Здравствуй ЛОР, я не знаю, как правильно задать вопрос… Постараюсь описать всё понятно, чтобы вы поняли, что меня интересует. Сразу скажу, что я не программист - я просто человек, который решил посмотреть на язык, испугался, и побежал на форум.

Дело было так: Я писал маленькую программку/скрипт на Golang. Её задачей было удалять тот файл, который не нужен, а его важность определял пользователь. В качестве эксперимента у меня лежала картинка doks.png. Сидя в VS Code мне приходилось вводить её полное название(doks.png), а мне хотелось только имя файла(doks). Я нажал [TAB], но вместо привычного терминального выбора близлежащего файла у меня сработал длинный перенос строки. Я подумал, что это проблема самого VS Code, запустил программу в Allacrity, но там было тоже самое. Тогда я решил, что если я скомпилирую проект в бинарник, проблема точно решится. Компиляция не помогла - оказалось, что перенос вызывает сам fmt.Scan(). Конец истории.

Вроде ничего страшного, но оно есть. Бинарник на выходе получил название родительской директории. Быть может это фиксится флагами, я ещё не разобрался. Страшно здесь то, что бинарник получился просто «бинарником». Ни .Appimage, ни .x86_64(как делает Godot). Это натолкнуло меня на мысль, что я неправильно понимаю идею Golang. Почитав где-то на Хабре про сборку пакетов, я увидел упоминания о go install, где предлагалось инсталлировать пакеты в папку установки языка, куда-то тоже в раздел с бинарниками. Это натолкнуло меня на другую мысль - а может Golang нужен, чтобы писать на нём какие-то демоны или или какие-то кусочки бэкенда в стиле «работает - не трогай»?

Единственный стиль установки программ, с которым я знаком, это виндовсовый. У тебя есть .exe - не просто чистый бинарник, а исполняемый бинарник конкретного стандарта. Он имеет свой путь, по которому он вызывается и получает аргументы(например: C:/Programm\ Files/MySoftware/Software.exe –help). В моём случае это больше похоже на какую-то запакованную программу, которая должна находиться строго с остальными, которая вызывается по её названию(команде), причём абсолютно не важно, где я сейчас нахожусь, хоть на примонтированном DVD-диске. Я правильно всё понимаю? Если да, то это больше похоже на поведение демонов или системных утилит, вроде top. Это нормально? Оно так и задумано? Есть ли тогда разница в «чистых бинарниках»(безформатных) и .appimage?

Идея двоичных исполняемых файлов UNIX в том, что это по большей части исполняемый код для того процессора, для которого этот двоичный исполняемый файл был скомпилирован. Поскольку это системный, и программно самый нижний уровень, то ниже уже некуда, и традиционно это ниша по большей части системных программ и разделяемых библиотек, а в некоторых архитектурах — также модулей ядра и самогО ядра UNIX. Интересующая Вас литература называется «Архитектура Компьютера», автор Эндри Танненбаум.

Infra_HDC ★★★★★
()

Golang тебе сделал не «чистый бинарник», а именно исполняемый бинарник конкретного стандарта - ELF (Executable and Linkable Format). Это такой же бинарник, как .exe в винде, только для Linux.

bigbit ★★★★★
()
Последнее исправление: bigbit (всего исправлений: 1)

Я нажал [TAB], но вместо привычного терминального выбора близлежащего файла у меня сработал длинный перенос строки

Что у тебя сработало?

исполняемый бинарник конкретного стандарта.

Любой бинарник это бинарник конкретного стандарта

ya-betmen ★★★★★
()

В чём идея Golang и UNIX-овых бинарников в целом?

Go — язык программирования.

Бинарники — любые данные в бинарном формате, то есть любые данные, под которые нет известной подходящей категории. Но имеются ввиду, скорее всего, исполняемые бинарные файлы. В случае юникса это машинные коды. Идея в том, что в момент запуска программы данные из этого файла загружаются в память для дальнейшей передачи в исполнение процессором.

Её задачей было удалять тот файл, который не нужен, а его важность определял пользователь. В качестве эксперимента у меня лежала картинка doks.png.

Такая программа уже есть: rm doks.png

Я нажал [TAB], но вместо привычного терминального выбора близлежащего файла у меня сработал длинный перенос строки.

Терминальный выбор делает сторонняя хрень readline. Не рекомендую отвлекаться на механизм её работы. Достаточно того, что чтение stdin не подразумевает никаких readline или прочей интерактивности, просто поток байт.

И это не перенос строки, а отступ. Перенос строки — это что-то из line feed, carriage return или enter.

Ни .Appimage, ни .x86_64(как делает Godot). Это натолкнуло меня на мысль, что я неправильно понимаю идею Golang.

AppImage — способ распространения программ.

Что такое x86_64 в контексте Godot я не знаю, но x86_64 — это архитектура процессора, соответственно, скорее всего, Godot собрал исполняемый файл под x86_64. go build, внезапно, делает тоже самое.

Почитав где-то на Хабре про сборку пакетов, я увидел упоминания о go install, где предлагалось инсталлировать пакеты в папку установки языка, куда-то тоже в раздел с бинарниками.

go install — способ установить чужую программу. А свою программу куда хочешь клади или устанавливай.

Это натолкнуло меня на другую мысль - а может Golang нужен, чтобы писать на нём какие-то демоны или или какие-то кусочки бэкенда в стиле «работает - не трогай»?

Способ установки и распространения программ не влияет на назначение языка. На го можно писать что угодно, если понимаешь как решать вытекающие проблемы. «Работает — не трогай» вообще неприменимо ни к какому языку программирования, это просто правило без глубоких рассуждений.

В моём случае это больше похоже на какую-то запакованную программу, которая должна находиться строго с остальными, которая вызывается по её названию(команде), причём абсолютно не важно, где я сейчас нахожусь, хоть на примонтированном DVD-диске.

Куда положишь свою программу — там она и будет лежать. Хочешь /bin/hello, хочешь /usr/john/hello, хочешь C:\Program Files\My Hello World\Hello.exe.

Для вызова из текущей директории достаточно ./hello, для вызова из другой директории — абсолютный или относительный путь.

Запуск по названию файла никак на это не влияет. Это просто шорткат, алиас, «Иван» вместо «Иван Иванович Иванов». Это реализовано с помощью решения (скорее костыля, но не важно), единого для винды и юниксов — переменной окружения PATH.

kaldeon
()
Последнее исправление: kaldeon (всего исправлений: 6)

Го, конечно, ненужен, но твоя тема - какой-то поток бреда. Вероятно, программирование на го уже повредило твой мозг, надо надеяться, что, пока что, обратимо. Бросай эту пакость и беги от неё, возможно вылечишься.

firkax ★★★★★
()

Гм, по-моему твой вопрос лежит в плоскости того, чем различаются разные способы пакетирования приложений.
Посмотри (например в википедии), что из себя представляет .appimage (и его конкуренты типа flatpack, snap); deb, rpm пакеты, а задно также про msi (пакеты для MS Windows).

MirandaUser2
()
Ответ на: комментарий от Infra_HDC

всёж mz elf и прочая pe это форматы которые парсятся загрузчиками перед собственно пуском

в отличие пристнопамятных bin и com которые буквально запускаются после копирования

так что нижний уровень это бинарь который просто копируется в раму и тудыть даже не call а jmp

и даже сom ожидает что первые 256 содержательно подготовленое окружение

так что нижний уровень это даже не всякий драйвер

нижний уровень это буквально поток машкодаданных который ещё и окружение тестирует самостоятельно для определения куда попал :)

qulinxao3 ★☆
()
Последнее исправление: qulinxao3 (всего исправлений: 1)

Есть ли тогда разница в «чистых бинарниках»(безформатных) и .appimage?

Разница в том, что кроме собственно программы-бинарника как правило нужны ассеты/ресурсы, т.е. картинки, звуки и прочие разного рода данные для работы программы. Программа в свою очередь рассчитывает найти это в определённом месте. Вот для этого нужны разного рода установщики, appimage и т.п. прибамбасы.

no-such-file ★★★★★
()
Ответ на: комментарий от kaldeon

Терминальный выбор делает сторонняя хрень readline.

И это не перенос строки, а отступ. Перенос строки — это что-то из line feed, carriage return или enter.

Спасибо большое!

скорее всего, Godot собрал исполняемый файл под x86_64. go build, внезапно, делает тоже самое.

Но Godot собрал исполняемый файл(он же бинарник?) с расширением .X86_64, а Go собрал такой же файл, но вообще без расширения

Для вызова из текущей директории достаточно ./hello, для вызова из другой директории — абсолютный или относительный путь.

А почему для вызова терминальных команд, вроде cd, dd, ffmpeg или btop, вручную не указывается путь к ним? Это тоже PATH?

Tyse_EX
() автор топика
Ответ на: комментарий от Tyse_EX

Но Godot собрал исполняемый файл(он же бинарник?) с расширением .X86_64, а Go собрал такой же файл, но вообще без расширения

В отличие от окошек, исполняемость файла в unix не опирается на концепцию расширения всем весом своего тела.

recei
()
Ответ на: комментарий от Tyse_EX

Добавь к своему go бинарнику .X86_64 или убери у годота, это ни что не влияет

Посмотреть какой формат бинарника можно в консоли file <твой бинарник>

masa ★★
()
Ответ на: комментарий от Tyse_EX

почему для вызова терминальных команд, вроде cd, dd, ffmpeg или btop, вручную не указывается путь к ним

Не для всякой команды есть отдельная программа со своим отдельным исполняемым объектным файлом. У каждого командного интерпретатора есть «встроенные» команды, которые инерпретатор выполняет сам.

Например, cd в системах, созданных по аналогии c UNIXом бессмысленно делать в виде отдельной программы. По завершении программы working directory останется тот же самый, что и до выполнения.

Вот, например, список встроенных команд GNU bashа, начинающихся на «c»

help -d c
caller - Return the context of the current subroutine call.
case - Execute commands based on pattern matching.
cd - Change the shell working directory.
command - Execute a simple command or display information about commands.
compgen - Display possible completions depending on the options.
complete - Specify how arguments are to be completed by Readline.
compopt - Modify or display completion options.
continue - Resume for, while, or until loops.
coproc - Create a coprocess named NAME.

Интерпретатор может обрабатывать сокращения и алиасы(псевдонимы) команд:

alias bls=/bin/ls
bls /
bin  boot  dev  etc  home  init  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

Интерпретор может искать программы для выполнения «внешних» команд в PATH (с помощью exec** или чего-то подобного), как Вы верно написали, или ещё в каких-то известных ему местах.

терминальных команд

И почему команды «терминальные»? 🙄

vM ★★
()
Последнее исправление: vM (всего исправлений: 2)

Добро пожаловать!

Не бывает глупых вопросов, бывают глупые ответы.

Надеюсь, следующее поможет пониманию:

Бинарный файл — тот, который, будучи разрезанным на байты, не образует человеко-читаемый текст.

Исполнимый файл — тот, из которого операционная система может изготовить процесс. Они не обязательно бинарные. Бинарные же форматы у разных ОС могут быть разные.

В Unix-подобных ОС расширение имени файла не играет той определяющей роли, что в Windows. Тип файла можно посмотреть командой file /путь/до/файла.

Вангую, что оба скомпилированных файла будут типа ELF (Executable and Linkable Format) x86_64.

Evenik ★★
()
Ответ на: комментарий от Tyse_EX

эрудиция не всегда вредна

у автора изначального Баурн шелла есть как книжка по использованию юникса ( есть на русском) так и интервью

представление об эволюции технических решений очень полезна для понимания какие трэйдоффы и чем они обусловленны и как оптимальности плывут при изменении стоимости компонент изделий по стреле времени

тот же PATH и вообще концепция переменных окружения это в целом ad-hoc решения - однако решатели достаточно высоколобы ,что бы это не так мешало, оказались

qulinxao3 ★☆
()

Начать нужно с C, языков ассемблера, чтения про форматы исполняемых файлов.

Да, советчик я не очень, много лет шел к пониманию каких-то вещей, исполнительная дисфункция ибо.

Но тут просто полный сумбур, невозможный.

  1. EXE - это три буковки в конце имени файла, больше ничего. В ФС какой-нибудь доси они были технически отделены от остальной части имени, да. А лежать внутри может дохрена разных форматов.

  2. В большинстве современных ФС имя файла - это все имя файла, и что там до точки, а что после точки - может различать только программа, его отображающая, там чтобы показать правильную иконку или спрятать для красоты.

  3. Когда ты запускаешь исполняемый файлик, ось не смотрит, что там написано в конце имени файла. Она смотрит на байтики в его начале. И дальше действует по ситуации.

  4. Все описанные решения проблем демонстрируют отсутствие причинно-следственных связей. Так не получится. Если есть горстка ситуаций «не так, как хочу» и гостка советов, любое от любого не поможет.

  5. Начинать писать скрипты лучше с языков оболочки, или с Tcl/Tk, или с Python. Там легко и понятно.

lealxe
()

Попробую подвести итоги.

Бинарный файл - это файл чисто машиночитаемого кода. Исполняемый файл - это тот файл, который содержит исполняемый машиной код. Исполняемый бинарник - это всё сразу.

Go build делает именно исполняемый бинарник(ELF), который может запускаться либо по прямому пути, либо(возможно) по своему названию, если ему будет задан аллиас или он будет находиться в /usr/bin.

В винде есть .exe и .msi, а в UNIX’ах они не нужны, потому что UNIX’ы смотрят не на расширение, а на кусочек байтов самого файла(вроде бы это называлось magic byte). Это не плохо и бояться этого не стоит.

А ещё у меня хроническая каша в голове…

Tyse_EX
() автор топика
Ответ на: комментарий от Tyse_EX

От каши в голове и как первое средство ликбеза рекомендую вам (и себе тоже) первую главу книги Керниган, Пайк, “Программное окружение UNIX”.

Если понравится, то и другие главы тоже, конечно.

Классика, которая не потеряла своего блеска.

Потом можно хоть в Си, хоть в Го, хоть куда хотите. Но начинать нужно с начала.

Evenik ★★
()
Последнее исправление: Evenik (всего исправлений: 1)
Ответ на: комментарий от Tyse_EX

Никакая это не каша. Для того, чтобы правильно задать вопрос, надо знать большую часть ответа. И ты это понимаешь, написав об этом в первой строчке.

bigbit ★★★★★
()
Ответ на: комментарий от Tyse_EX

Исполняемый файл - это тот файл, который содержит исполняемый машиной код.

НЕТ - исполняемость определяется «интерпритирующей системой» если пускатель асоциирует odt файл с приложением которое выполнит макросы при открытии а эти макросы совершат необратимое то файл исполняем хотя и «документ» - вот именно поверье что исполняемый обязан быть машкодным и приводет к дырам в безопасности ибо это же все голишь .lnk - это же всеголишь .pdf

Исполняемость определяется загрузчиком

вот для чатгопоты промт есть исполняемый файл

qulinxao3 ★☆
()
Ответ на: комментарий от lealxe

утилиты хоть сli хоть уеб

python достаточен

рекомендую всем https://docs.marimo.io/examples/

ибо живокодинг и интерактивно

ну и ipython

а всё в vscode :)

https://youtu.be/Z1orytkBzwo

qulinxao3 ★☆
()
Последнее исправление: qulinxao3 (всего исправлений: 3)
Ответ на: комментарий от cobold

...не написал какую задачу решаешь.

А это что? --

"...писал маленькую программку/скрипт на Golang. Её задачей было удалять тот файл, который не нужен, а его важность определял пользователь."

sparkie ★★★★★
()
Ответ на: комментарий от Tyse_EX

В винде есть .exe и .msi, а в UNIX’ах они не нужны

В виндовом .exe тоже ничего особенного. Это просто соглашение для удобства, как .appimage

cmd.exe /k
echo %PATHEXT%

.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC

mkdir test&cd test&copy %windir%\system32\fc.exe app.elf
dir app* /b

app.elf

set PATHEXT=.ELF
app /?
Сравнение двух файлов или двух наборов файлов
и вывод различий между ними.


FC [/A] [/C] [/L] [/LBn] [/N] [/OFF[LINE]] [/T] [/U] [/W]
   [/nnnn][диск1:][путь1]имя_файла1 [диск2:][путь2]имя_файла2
FC /B [диск1:][путь1]имя_файла1 [диск2:][путь2]имя_файла2

  /A         Вывод только первой и последней строк для каждой группы различий.
. . . . 
. . . .

Сами же .appimage – исполняемые ELF, согласно спецификации https://github.com/AppImage/AppImageSpec/blob/master/draft.md#type-1-image-format:

od -a -N 16 LibreOffice-still.basic-x86_64.AppImage
0000000 del   E   L   F stx soh soh nul   A   I stx nul nul nul nul nul
0000020
file LibreOffice-still.basic-x86_64.AppImage
LibreOffice-still.basic-x86_64.AppImage: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=30e06184968532b6a9aa36f44ada39e4af0bda56, for GNU/Linux 2.6.32, stripped
readelf -hl LibreOffice-still.basic-x86_64.AppImage
ELF Header:
  Magic:   7f 45 4c 46 02 01 01 00 41 49 02 00 00 00 00 00
  Class:                             ELF64
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       65
  Type:                              EXEC (Executable file)
  Machine:                           Advanced Micro Devices X86-64
  Version:                           0x1
  Entry point address:               0x405fc8
  Start of program headers:          64 (bytes into file)
  Start of section headers:          191680 (bytes into file)
  Flags:                             0x0
  Size of this header:               64 (bytes)
  Size of program headers:           56 (bytes)
  Number of program headers:         11
  Size of section headers:           64 (bytes)
  Number of section headers:         32
  Section header string table index: 31

Program Headers:
  Type           Offset             VirtAddr           PhysAddr
                 FileSiz            MemSiz              Flags  Align
  PHDR           0x0000000000000040 0x0000000000400040 0x0000000000400040
                 0x0000000000000268 0x0000000000000268  R      0x8
  INTERP         0x00000000000002a8 0x00000000004002a8 0x00000000004002a8
                 0x000000000000001c 0x000000000000001c  R      0x1
      [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
  LOAD           0x0000000000000000 0x0000000000400000 0x0000000000400000
                 0x0000000000004078 0x0000000000004078  R      0x1000

anonymous
()
Ответ на: комментарий от Tyse_EX

выполняются как CLI

Для того, чтобы использовать CLI программ из своей программы, терминал необязателен. Аргументы программе передаются с помощью соответствующего API, а стандартный ввод, вывод и т.д. можно перенаправить и обрабатывать.

https://go.dev/play/p/M9GpMIKxfxC

package main

import (
	"log"
	"os/exec"
)

func main() {
	out, err := exec.Command("sh", "-c", "help").Output()
	if err != nil {
		log.Fatal(err)
	}
	log.Println("ok")
	log.Println(out)
}
vM ★★
()
Ответ на: комментарий от Tyse_EX

Не всё так просто, несмотря на то что в бинарниках чистый машинный код, там ещё есть данные для операционки куда эти бинарные куски в памяти разместить и с какими параметрами. Вот тут этих форматов целый список.

Алиас существует только внутри шелла, как встроенные команды, шелл просто заменяет алиасы на их значения. А находиться бинарник может где угодно в $PATH (даже на винде это есть), не только в /usr/bin, ну и да, само собой, его можно запустить через абсолютный путь.

В винде есть .exe .msi, в *NIX чего только нет: .deb, .rpm, appimage, snap, flatpak, .tar.gz, итд. Расширение в никсах ничего не значит, значит только executable bit в правах на файл. Потому что исполняемым можно сделать даже тупо текстовый файл на питоне или шелле, но ОС часто нужна помощь в виде шебанга чтобы понять каким интерпретатором его запустить. Винда тоже так умеет, но ориентируется на зарегистрированные в реестре программы и расширения файлов которые они умеют открывать (для особой путаницы графические окружения в никсах и это тоже умеют на всякие двойные клики по файлу).

neumond
()

ДоброКорп оказался своими действиями в положении когда жонглирование серверами на которых крутятся python алгосы дёргающие с++ алгосы фундамента перестало экспоненциально расти ибо само управления достигло пределов сложности

для увеличение raw существенную долю python-пехоты перевели в go-пехоту ибо barebone golang экономней чем python c gil

т/е когда рост экстенсивный достиг низа рентабельности пошли расти в глуб оптимизируя язык предпочли использовать наработки Пайка Томсона в части мультиконкурентного «так совпало». что как раз Мур на одноядрах «остановился» при продолжающейся минитюаризации

qulinxao3 ★☆
()
Ответ на: комментарий от anonymous

В виндовом .exe тоже ничего особенного.

Верно. На Windows 10

copy %windir%\write.exe linux.org.ru & linux.org.ru

wordpad запустился. Но, возможно, не найдет свои MUI ресурсы, а так всё работает, как ожидается.

vM ★★
()
Ответ на: комментарий от vM

света мала

не (достаточно) умеют в обратимые вычисления следовательно тепло

да и в целом клеточная машина вселенной массово паралельно (таково восприятие) - поэтому очевидно и выч машину нуна конкурентной - аказывается первые эвм (которые без памяти были ) конктруктивно изначально были и паралельны

обращение к памяти оказалось точкой рандеву тактирующию всё систему

забавно с начала теория относительности (спец общ хз) с конусом миньковского затем успехи в химфизики ШоклиИко в точечных транс(исторах) и только потом массовые эвм :)

qulinxao3 ★☆
()
Ответ на: комментарий от kaldeon

хз

речь скорее по заполнение лабиринта эвристикой А* в которой если предполагать телецель порядок фактической хронологии событий оказывается не совпадает в порядке оптимального по времени(али какому иному ресурсу) дерева из грант-диаграммы

имхо выч маш (машины Бэбиджа) была реально построена к 1870 - что проявилось в некоторых не очевидных действиях спонсоров

qulinxao3 ★☆
()