Как передать аргументы командной строки скрипту вместо оболочки

У меня есть скрипт tcl/tk, который я запускаю через wish. Однако я заметил, что некоторые аргументы командной строки передаются в пожелание вместо моего сценария. Например, если я наберу ./script -h, я получу вывод справки по желанию вместо вывода справки по моим сценариям.

Это демонстрирует следующий код, где puts $arvg должен показывать аргументы командной строки. Если я использую аргументы, которые не используются по желанию, например "-i", то они корректно передаются моему скрипту и распечатываются.

#!/usr/bin/env/ wish

puts $argv

Как я могу обеспечить передачу аргументов командной строки моему сценарию, а не интерпретатору?

Я удалил свой ответ. Аргумент -- в wish означает не «это последний аргумент без опций», а «это последний аргумент, имеющий какое-либо значение для wish». Ой!

Kaz 02.10.2022 02:53
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
1
216
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Для программ с хорошим поведением один из возможных ответов будет таким:

#!/usr/bin/env -S interpreter --

interpreter, что бы это ни было, будет рассматривать -- как аргумент последнего варианта. Затем он будет рассматривать следующий аргумент как имя сценария, а остальные аргументы — как аргументы сценария.

Увы, wish не подчиняется этому соглашению. Хотя он поддерживает --, этот аргумент означает, что «это последний аргумент, который wish обрабатывает сам; все остальное передается сценарию». Аргумент после -- не обрабатывается как файл сценария для чтения.

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

Лучшим вариантом может быть оболочка-оболочка:

#!/bin/sh
myname=$0
tkscript = "${myname%.sh}.tcl"
exec wish "$tkscript" -- "$@" # Thanks to Donal K. Fellows for exec reminder.

Идея в том, что у вас есть вышеуказанный скрипт под именем, скажем, foo.sh. В том же каталоге, что и foo.sh, есть foo.tcl скрипт: настоящий.

Идея состоит в том, что если приведенный выше скрипт вызывается как /path/to/foo.sh, он вычислит имя соседнего скрипта как /path/to/foo.tcl. Это передается в качестве аргумента wish, затем опция --, чтобы сказать «это последний аргумент, обработанный wish», а затем собственные аргументы скрипта, которые больше не интерпретируются wish, даже если они выглядят как опции wish.

Возможно, вам не нужен суффикс .sh, а просто назовите его именем без суффикса, например foo, и в этом случае назначение tkscript упрощается до:

tkscript = "${myname}.tcl"

Используйте exec wish ..., чтобы не создавать новый процесс; вы просто настраиваете параметры запуска.

Donal Fellows 02.10.2022 13:11

@DonalFellows Может быть, настало время, когда оболочки вставляются в устранение хвостового вызова сами; кто может не забыть выполнить последнюю строку?

Kaz 03.10.2022 04:39

Патч, который я первоначально предложил для GNU Coreutils env (с работающей реализацией, документацией и тестовыми примерами), справится с этой ситуацией; Я поддержал нотацию {}, чтобы указать, где в аргументах должно быть вставлено имя скрипта.

Kaz 03.10.2022 04:44

Оболочки предполагают, что вы пишете то, что имеете в виду. По умолчанию оболочки выполняют пост-обработку результатов ваших вызовов (для таких мелочей, как обнаружение сбоев, информация, которую вы в данном случае выбрасываете), поэтому они не могут просто предположить, что вы намеревались полностью делегировать выполнение. Если вы хотите этого, вам нужно написать exec, чтобы сказать это. Это правило.

Donal Fellows 03.10.2022 13:46

Вместо того, чтобы вызывать желание в шебанге (напрямую или через env), вызовите tclsh. Таким образом, вы можете манипулировать $argv, который увидит Tk:

#!/usr/bin/env tclsh

# Copy the command line arguments to a new variable
set arglist $argv

# Turn tclsh into wish without passing the command line options
set argv {}
package require Tk

puts $arglist

Обычно я выполняю всю свою обработку командной строки перед package require Tk. Итак, перед запуском Tk необходимо только очистить argv.

Другие вопросы по теме