예를 들어, 내가 가지고 있는
alias dbmigrate='rails db:migrate'
Bash 및 Zsh에서 셸에 입력할 때 다음과 같이 구성할 수 있는 모드나 간단한 방법이 있습니까?
$ dbmigrate # press Enter
별칭을 실행하기 전에 확장되는 내용을 반영합니까?
답변1
~ 안에세게 때리다alias-expand-line
, 및 readline 함수가 있지만 history-and-alias-expand-line
기본적으로 어떤 키에도 바인딩되어 있지 않습니다. 직접 바인딩할 수 있습니다. 예를 들면 다음과 같습니다 Control-T
.
bind '"\C-T": history-and-alias-expand-line'
바인딩 Enter
자체를 시도하는 것은 지저분할 수 있습니다. 왜냐하면 누를 때마다 Enter
명령이 실행되지 않기 때문입니다(예: 불완전한 파이프라인인 경우 등).
트랩 도 있지만 DEBUG
명령이 실제로 사용자에 의해 입력되었는지(예: PROMPT_COMMAND
의 명령 대체에서 시작되지 않았는지 PS1
) 여부와 별칭 확장 여부를 결정하는 것은 까다로울 것입니다. 하지만 인쇄해도 괜찮다면어느실행 전 명령:
trap 'echo "> $BASH_COMMAND"' DEBUG
bash$ pwd
> pwd
~ 안에zshpreexec
, 사용자가 입력한 명령과 다른 경우 확장된 명령을 인쇄하는 함수를 간단히 정의할 수 있습니다 .
preexec(){ [ $1 != $2 ] && print -r "> $2" }
zsh$ j
> jobs
그러나 별칭을 강제로 확장하면 일부 별칭 + 기록 트릭이 제대로 작동하지 않는다는 점에 유의하세요. 예를 들어, c
bash에는 , 등을 이스케이프하지 않고도 와 같은 계산을 수행할 수 있는 별칭 c 3.17 * 4.2
이 있습니다 .*
(
alias c='_c=$(fc -nl -0); bc -l <<<${_c#*c} #'
readline이 그것을 확장하면, 히스토리의 현재 라인( 에 의해 반환된 라인 fc -nl -0
)은퍼지는, 원래 명령이 아니므로 모든 것이 무너질 것입니다.
답변2
별칭은 단순한 대체일 뿐입니다. 명령을 실행하기 전에 메시지를 인쇄하는 등 더 멋진 작업을 수행하려면 더 강력한 기능, 즉 함수가 필요합니다. 정의가 별칭 정의처럼 보이도록 하려면 함수를 정의하는 함수를 정의하면 됩니다.
function verbose_alias {
local name=${1%%=*} expansion=${1#*=}
eval "function $name {
printf >&2 '%s is an alias for %s\\n' \"$name\" \"$expansion\";
$expansion \"\$@\";
}"
}
verbose_alias dbmigrate='rails db:migrate'
답변3
POSIX에는 다음이 필요합니다.set
명령이 옵션을 가지려면
-x
쉘은 명령을 확장한 후 실행하기 전에 각 명령에 대한 추적을 표준 오류에 기록합니다. 추적을 끄는 명령이 추적되는지 여부는 지정되지 않습니다.
https://pubs.opengroup.org/onlinepubs/009604499/utilities/set.html
따라서 호환되는 쉘에서 set -x
또는 을 사용할 수 있습니다. set -o xtrace
Bash에서는 매뉴얼 페이지에서 다음을 볼 수 있습니다.
-x
각 단순 명령, 명령의 경우, 대소문자 명령, 선택 명령 또는 명령의 산술을 확장한 후 PS4의 확장된 값을 표시하고 그 뒤에 명령과 확장된 인수 또는 관련 단어 목록이 표시됩니다.
xtrace
와 동일합니다
-x
.
zsh에도 비슷한 옵션이 있습니다.set
내장
XTRACE(
-x
, ksh:-x
)실행되는 명령과 해당 인수를 인쇄합니다.
-x
스크립트나 명령을 실행하는 동안 옵션을 지정할 수도 있습니다.
bash -x -c "echo This will be printed before running; ll"
bash -x script-to-be-debugged.sh
zsh -x -c "...; 3; md did-you-see-the-aliases"
zsh -x buggy-script.sh
또한 각 프롬프트 전후에 실행되는 명령을 확장하므로 git
PS1에서 변수를 사용하는 경우와 같은 많은 상황에서는 바람직하지 않을 수 있습니다. 내 깨끗한 Ubuntu VM에서는 실행 중인 명령만 인쇄됩니다.
또한보십시오무엇을 set -x
합니까?
또 다른 옵션은 set -v
또는 set -o verbose
인쇄하기 전에 변수를 확장하지 않는 것입니다.
답변4
Bash에서는 기본적으로 이러한 종류의 도움말을 사용할 수 없습니다.
기본적으로 사용할 수 있는 두 가지 관련 기능은 다음과 같습니다.
shopt -s histverify
설정되고 readline이 사용되는 경우 기록 대체 결과가 즉시 쉘 파서로 전달되지 않습니다. 대신 결과 라인이 readline 편집 버퍼에 로드되어 추가 수정이 가능해집니다.
를 눌렀을 때 작업의 일부를 처리 Enter
하지만 명령줄의 기록 확장만 사용합니다. 예를 들어:
$ shopt -s histverify
$ echo "this is a test"
This is a test
$ echo !!
$ echo echo "this is a test" <---- expanded by the simple use of enter!!
- Readline
shell-expand-line
쉘 확장 라인(MCe)
쉘처럼 행을 확장하십시오. 이는 모든 쉘 단어 확장뿐만 아니라 별칭 및 기록 확장도 수행합니다. 히스토리 확장에 대한 설명은 아래의 HISTORY EXPANSION을 참조하세요.
이것이 바로 귀하가 요청한 작업입니다. 그러나 이를 작동시키는 열쇠는 Ctrl다음 과 Alt같습니다.e
Enter 및 Execute와 함께 작동하는 솔루션을 알지 못합니다 shell-expand-line
. 죄송합니다.