Как заменить утилиты Mac OS X на основные утилиты GNU?

Я обнаружил, что есть некоторые различия между служебной командой, которую я использовал в Mac OSX и Linux. Я хочу объединить свой опыт.

Как я могу заменить все свои утилиты для Mac на утилиты GNU?

Вот руководство topbug.net/blog/2013/04/14/…
Я сочувствую вашему разочарованию, но я считаю, что в долгосрочной перспективе их замена вызовет еще большее разочарование . После попытки сделать то же самое я бы рекомендовал использовать homebrew, как указано ниже, а затем просто научиться использовать утилиты с a g( gsed, greadlink, и т. д. ) вместо замены системных утилит.
Я не согласен с @cwd, использование --with-default-namesвлияет только на локального пользователя. Это может быть проблема с утилитами терминала, ориентированными на Mac, но если вы используете homebrew для всего, вы также можете притвориться, что используете Linux. Смешанный с iterm2, он отлично работает для меня, я могу в основном притворяться, что я дома со своими Linux-боксами.
ПРИМЕЧАНИЕ: cpи mvможет быть опасным для расширенных атрибутов файла (например, тегов, невидимости, псевдонима, пакета и т. д.). Подробнее см. в этих двух статьях: bretttrpstra.com/2014/07/03/… bretttrpstra.com/2014/07/04/how-to-lose-your-tags Они немного устарели, но я просто хочу поднять предупреждение, чтобы вы могли исследовать, если вы используете GNU, mvи оно cpбудет мешать вашим потребностям.
Есть ли у кого-нибудь конкретный пример, демонстрирующий, что это «вызовет большее разочарование»?
@cambunctious конкретный пример: скрипт, который использует утилиту по умолчанию для вашей системы, сломается.
@DeNovo это не конкретно
@boileau Я бы сказал, что это достаточно конкретно. Любой сценарий установки для пакета, который пытается использовать ваши утилиты по умолчанию в зависимости от вашей ОС, может завершиться ошибкой или делать странные вещи и вызывать странные ошибки. Это было бы довольно болезненно, я думаю. Когда это произойдет, кто знает, но вполне вероятно!
@CodeNovitiate извините, но фраза «вот расплывчатая категория вещей, которые могут произойти» не является конкретной. Конкретным будет ссылка на сценарий, который не работает, и описание того, как это сделать.

Ответы (6)

Это добавляет символические ссылки для утилит GNU с префиксом g в /usr/local/bin/:

brew install coreutils findutils gnu-tar gnu-sed gawk gnutls gnu-indent gnu-getopt grep

Смотрите brew search gnuдругие пакеты. Если вы хотите использовать команды без префикса ag, добавьте, например, /usr/local/opt/coreutils/libexec/gnubinперед другими каталогами в вашем PATH.

$ brew info coreutils
coreutils: stable 8.21
http://www.gnu.org/software/coreutils
Depends on: xz
/usr/local/Cellar/coreutils/8.20 (208 files, 9.4M)
/usr/local/Cellar/coreutils/8.21 (210 files, 9.6M) *
https://github.com/mxcl/homebrew/commits/master/Library/Formula/coreutils.rb
==> Caveats
All commands have been installed with the prefix 'g'.

If you really need to use these commands with their normal names, you
can add a "gnubin" directory to your PATH from your bashrc like:

    PATH="/usr/local/opt/coreutils/libexec/gnubin:$PATH"

Additionally, you can access their man pages with normal names if you add
the "gnuman" directory to your MANPATH from your bashrc as well:

    MANPATH="/usr/local/opt/coreutils/libexec/gnuman:$MANPATH"
FWIW, у меня есть Homebrew Formula, которая действует как метапакет для всех этих замечательных утилит GNU: см. shiny-and-gnu.rbgithub.com/al-the-x/homebrew-mine .
Первый PATH работает, а MANPATH не работает, почему? Это потому, что я использую OSX10.10? Я повторил $MANPATH, и я получил /usr/local/opt/coreutils/libexec/gnuman:, кажется, оригинальный MANPATH не был включен. После того, как я закомментировал конфиг MANPATH в моем bashrc, я ничего не получил от ecoh $MANPATH. И, конечно же, если я использую man pwd, у меня есть руководство по BSD. Как это исправить?
Для findutils, вам нужно добавить PATH="/usr/local/Cellar/findutils/4.4.2/bin:$PATH"то, что не указано в выводе консоли установки.
Кроме того, чтобы получить правильную справочную страницу для findutils, добавьте ее в свой$MANPATH /usr/local/opt/findutils/share/man
@Zen: правильный способ инициировать MANPATH, чтобы сохранить системное значение по умолчанию: MANPATH="/usr/local/opt/coreutils/libexec/gnuman:${MANPATH-/usr/share/man}". Ключ в конструкции ${var-default_value}.
Доступен ли пакет, который устанавливает все эти инструменты одновременно?
Я запускаю это для создания символических ссылок в моем каталоге ~/bin: utilDir=coreutils/8.25; cp -a /usr/local/Cellar/${utilDir}/libexec/gnubin/* ~/binпросто измените utilDirдля каждого набора утилит, которые вы хотите связать. Затем я могу просто установить `PATH="/home/me/bin:$PATH", не создавая такого беспорядка с разными каталогами.
@danielAzuelos, кажется, в вашем фрагменте есть какие-то странные символы Unicode, которые появляются при копировании и вставке: i.imgur.com/qQWygg2.png
@Sridhar-Sarnobat Для чего это?
Я не помню. Но мне это было нужно, чтобы моя работала. Я предполагаю, что он не будет использовать версию GNU findили какую-либо другую распространенную программу, о которой вы всегда можете сказать, когда получаете сообщение об ошибке, используя findбез аргумента каталога.
Настройка PATH="/usr/local/opt/coreutils/libexec/gnubin:$PATH"помогла. Спасибо!

Кроме того brew install coreutils, вам также может понадобиться установить некоторые другие пакеты, такие как gnu-sed:grep

brew install findutils
brew install gnu-indent
brew install gnu-sed
brew install gnutls
brew install grep
brew install gnu-tar
brew install gawk

Обратите внимание, что этот --with-default-namesпараметр удален с января 2019 года, поэтому каждый двоичный файл необходимо добавить в путь, если он будет использоваться без gпрефикса.

Старая ссылка (когда --with-default-namesбыла доступна): http://www.topbug.net/blog/2013/04/14/install-and-use-gnu-command-line-tools-in-mac-os-x/

Обратите внимание, что brew install gawk(в отличие от всех остальных) заменит awk(через символическую ссылку /usr/local/bin/awk). Если вы хотите сохранить оригинал /usr/bin/awk, простоrm /usr/local/bin/awk
Доступна ли версия GNU ping?
@HappyFace Я так не думаю. В GNU/Linux pingэто утилита ядра Linux: github.com/iputils/iputils

Я не уверен, что порекомендовал бы их заменить ; однако вы можете установить их по другому пути и использовать таким образом. В целом, если вы работаете с Linux и хотите получить доступ к более «универсальным» утилитам *nix и системе, похожей на apt, я бы порекомендовал изучить Macports: http://www.macports.org

Это позволяет, например, использовать последний «общий» GCC, в отличие от / в дополнение к включенному Apple GCC, просто в качестве примера.

Например, tar и zip из Mac OS X знают о метаданных, которых нет в версиях GNU.
Существуют приложения, поставляемые Apple, которые являются просто графическими интерфейсами для некоторых инструментов командной строки, и если вы замените их, приложения могут начать вести себя странно, поэтому добавляйте, а не заменяйте.
Правильно; что-то вроде Macports добавляет их, а не заменяет.
Если вы хотите использовать утилиты GNU по умолчанию с MacPorts, вы можете добавить /opt/local/libexec/gnubinих в начало PATHпеременной среды.

Я написал сценарий, чтобы сделать именно это! Скрипт можно посмотреть здесь (или ниже). Однако я не всегда могу гарантировать, что этот пост будет отражать последнюю версию скрипта, связанного ранее.

После запуска скрипта будет установлен Homebrew (если он еще не установлен), будут установлены все связанные утилиты GNU (если они еще не установлены), а PATHпеременная будет создана из установленных утилит.

#!/bin/bash

# Install Homebrew (if not already installed)
/bin/bash -c "$(curl -fsSL "\
"https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

# Install required packages from Homebrew
brew tap homebrew/dupes
brew install coreutils binutils diffutils ed findutils gawk gnu-indent gnu-sed \
  gnu-tar gnu-which gnutls grep gzip screen watch wdiff wget bash gdb gpatch \
  m4 make nano file-formula git less openssh python rsync svn unzip vim \
  --default-names --with-default-names --with-gettext --override-system-vi \
  --override-system-vim --custom-system-icons

# Empty the .bash_path file that holds GNU paths
[[ -f ~/.bash_path ]] && mv ~/.bash_path ~/.bash_path.orig

# Build PATH variable script in ~/.bash_path
for i in /usr/local/Cellar/*/*/bin; do
  echo 'export PATH="'$i':$PATH"' >> ~/.bash_path
done
for i in /usr/local/Cellar/*/*/libexec/gnubin; do
  echo 'export PATH="'$i':$PATH"' >> ~/.bash_path
done
for i in /usr/local/Cellar/*/*/share/man; do
  echo 'export MANPATH="'$i':$MANPATH"' >> ~/.bash_path
done
for i in /usr/local/Cellar/*/*/libexec/gnuman; do
  echo 'export MANPATH="'$i':$MANPATH"' >> ~/.bash_path
done

# Check if .bash_path is being called from .bash_profile
PATCH=`grep "~/.bash_path" ~/.bash_profile`
if [ "$PATCH" == "" ]; then
  # Add Ubuntu-style PS1 to .bash_profile
  cat <<EOF > ~/.bash_profile
export PS1="\[\033[1;32m\]\u@\h\[\033[0m\]:\[\033[1;34m\]\w\[\033[0m\]# "
EOF
  # Add .bash_path to .bash_profile
  echo "source ~/.bash_path" >> ~/.bash_profile
fi

Я написал сценарий, который прозрачно преобразует интерфейс командной строки macOS в новый интерфейс командной строки GNU/Linux.

  • установка отсутствующих программ GNU
  • обновление устаревших программ GNU
  • замена предустановленных программ BSD их предпочтительной реализацией GNU
  • установка других программ, распространенных среди популярных дистрибутивов GNU/Linux

https://github.com/fabiomaia/linuxify

git clone https://github.com/fabiomaia/linuxify.git
cd linuxify/
./linuxify install

Это также позволяет вам легко отменить все.

./linuxify uninstall
Попытка запустить первую команду ( git clone git@github.com.:fabiomaia/linuxify.git). Сначала она сказала: «Подлинность хоста« github.com »не может быть установлена ​​​​и т. Д.». Я набрал yesи нажал Enter. Затем он сказал git@github.com: Permission denied (publickey). fatal: Could not read from remote repository. Please make sure you have the correct access rights and the repository exists., что не так?
@izogfif Попробуйте вместо этого клонировать с помощью HTTPSgit clone https://github.com/fabiomaia/linuxify.git
Да, это сработало. Пожалуйста, обновите свой ответ (также удалите эти доллары в начале - они копируются при выборе текста и копировании и вставке в консоль).
@izogfif Спасибо за предложения.

В качестве альтернативы установке переменных среды PATH и MANPATH (что я бы рекомендовал) также можно символически связать двоичные файлы с существующим местоположением PATH следующим образом:

Вам нужно знать, куда Homebrew устанавливает coreutilsбинарные файлы.

/usr/local/opt/coreutils/bin

В /usr/local/optэтом каталоге Homebrew хранит относительно статические файлы, которые вряд ли изменятся между обновлениями.

Затем вы можете создать оттуда символические ссылки на местоположение, которое уже находится в вашем PATH. Это должен быть путь, загружаемый в PATH на ранней стадии, поскольку поиск в PATH осуществляется в порядке поступления. /usr/local/binхороший выбор, основанный на просмотре echo $PATH.

which sha256sum # prove it is not on PATH
ln -s /usr/local/opt/coreutils/bin/sha256sum /usr/local/bin/
which sha256sum # prove it is on PATH

Таким образом, было бы почти так же легко создавать символические ссылки. В некоторых случаях, например, когда вам нужен более жесткий контроль, это хороший вариант, а не добавление всего каталога в ваши PATH и MANPATH.