다음 기능을 사용하여 bash 스크립트를 작성하는 방법이 있습니까?
- 특정 키나 키 조합을 누르면 실행됩니다. (그렇게 중요한 요구사항은 아님)
- 지난 3시간 동안 가장 많이 방문한 디렉토리 7개를 식별합니다.
- 탭과 Shift-Tab(뒤로)을 사용하여 순환할 수 있도록 이 7개의 디렉터리 목록을 제공하세요. 그런 다음 Enter를 누르면 선택한 디렉토리로 CD를 이동하는 것을 의미합니다.
감사해요
답변1
파일 에 다음을 추가합니다 ~/.bashrc
.
#### cd history mechanism ##############################################
export CDHISTFILE=~/.cdhistory
if [ -e "$CDHISTFILE" ]
then
cdht=`mktemp`
tail -500 "$CDHISTFILE" > $cdht
mv "$cdht" "$CDHISTFILE"
fi
function keep_cd_history() {
if [ -z "$1" ] ; then d="$HOME" ; else d="$1" ; fi
cdhcan=`readlink -f "$d"`
if 'cd' "$d"
then
echo -e `date +%s`"\t"$cdhcan >> $CDHISTFILE
fi
}
function pick_cwd_from_history() {
f=~/.cdhistgo
cdhistpick "$f"
if [ -r "$f" ] ; then cd "`head -1 $f`" ; fi
}
alias cd=keep_cd_history
alias cdh=pick_cwd_from_history
########################################################################
CD 기록 메커니즘의 사용자 정의 기록 파일이 마지막으로 본 이후 500줄보다 길어지면 첫 번째 부분에서 파일이 잘립니다. Bash의 내장 기록은 "지난 3시간 동안"의 동작을 얻는 데 필요한 타임스탬프를 포함하지 않기 때문에 사용할 수 없습니다.
이 두 Bash 함수는 아래 Perl 코드에서 수행할 수 없는 작업을 수행합니다. 그렇지 않으면 모든 무거운 작업을 수행하게 됩니다. 여기서 유일하게 까다로운 부분은 readlink
사용하는 경로를 정규화하는 호출입니다. 기록 에 4개의 다른 항목이 아닌 cd $HOME ; cd ; cd ~ ; cd ../$USER
동일한 경로의 4개 인스턴스가 있도록 이 작업을 수행해야 합니다.cd
별칭은 함수에 대한 편리한 래퍼일 뿐입니다.
이제 정말 까다로운 부분은 다음과 같습니다.
#!/usr/bin/perl -w
use strict;
use List::Util qw(min);
#### Configurables #####################################################
# Number of seconds back in time to look for candidate directories
my $history_seconds_threshold = 3 * 60 * 60;
# Ignore directories we have gone to less than this many times
my $access_count_threshold = 1;
# Number of directory options to give in pick list
my $max_choices = 7;
#### DO NOT OPEN. NO USER-SERVICEABLE PARTS INSIDE. ####################
# Get file name our caller wants the cd choice to be sent to
die "usage: $0 <choice_file>\n" unless $#ARGV == 0;
my $cdhg_file = $ARGV[0];
unlink $cdhg_file; # don't care if it fails
# Build summary stats from history file to find recent most-accessed
my $oldest_interesting = time - $history_seconds_threshold;
my %stats;
open my $cdh, '<', "$ENV{HOME}/.cdhistory" or die "No cd history yet!\n";
while (<$cdh>) {
chomp;
my ($secs, $dir) = split /\t/;
next unless $secs and $secs >= $oldest_interesting;
++$stats{$dir};
}
# Assemble directory pick list
my @counts = sort values %stats;
$access_count_threshold = $counts[$max_choices - 1] - 1
if @counts > $max_choices;
my @dirs = grep { $stats{$_} > $access_count_threshold } keys %stats;
$max_choices = min($max_choices, scalar @dirs);
# Show pick list, and save response to the file pick_cwd_from_history()
# expects. Why a file? The shell must call chdir(2), not us, because
# if we do, we change only our CWD. Can't use stdio; already in use.
my $choice;
if ($max_choices > 1) {
for (my $i = 0; $i < $max_choices; ++$i) {
print $i + 1, '. ', $dirs[$i], "\n";
}
print "\nYour choice, O splendid one? [1-$max_choices]: ";
$choice = <STDIN>;
chomp $choice;
exit 0 unless $choice =~ /^[0-9]+$/ && $choice <= $max_choices;
}
elsif ($max_choices == 1) {
print "Would you like to go to $dirs[0]? [y/n]: ";
$choice = 1 if uc(<STDIN>) =~ /^Y/;
}
else {
die "Not enough cd history to give choices!\n";
}
if ($choice) {
open my $cdhg, '>', $cdhg_file or
die "Can't write to $cdhg_file: $!\n";
print $cdhg $dirs[$choice - 1], "\n";
}
이라는 파일에 저장하고 cdhistpick
실행 가능하게 만든 다음 에 넣습니다 PATH
. 직접 실행하지는 않습니다. cdh
필요한 매개변수를 전달하므로 이에 대한 별명을 사용하십시오 pick_cwd_from_history()
.
어떻게 작동하나요? 글쎄요, 독자들을 위한 연습이요? :)
첫 번째 요구 사항(단축키)을 충족하려면 선택한 운영 체제에 적합한 매크로 기록 프로그램을 사용할 수 있습니다. 그냥 입력 cdh
하고 누르기만 하면 됩니다. Enter또는 cdh
입력하기 쉽기 때문에 직접 실행할 수도 있습니다.
Ctrl어디에서나 작동하는 간단하지만 기능이 덜 풍부한 대안을 원한다면 Bash의 역증분 검색 기능을 사용하는 습관을 가지세요 R. 해당 키를 누른 다음 "cd"(따옴표 없이 뒤에 공백 포함)를 입력하여 이전 cd
명령으로 돌아갑니다. 그런 다음 Ctrl- 를 누를 때마다 이전 명령 R으로 돌아갑니다 . cd
이렇게 하면 cd
Bash의 기록 기능 범위 내에서 지정한 모든 명령을 거꾸로 작업할 수 있습니다.
설명하다:
$ echo $HISTFILESIZE
Bash 기록이 얼마나 많은 명령줄을 저장할지 확인하세요. 3시간의 명령 기록을 저장하려면 이 값을 늘려야 할 수도 있습니다.
명령 기록을 뒤로 검색한 후 앞으로 검색하려면 Ctrl- 를 누르세요 S.
이것이 귀하의 시스템에서 작동하지 않는다면, 그 이유는 다음과 같습니다:소프트웨어 흐름 제어. 다음 명령을 사용하여 문제를 해결할 수 있습니다.
$ stty stop undef
이렇게 하면 Ctrl-S가 XOFF 문자로 해석되는 것을 방지할 수 있습니다.
그 결과 더 이상 Ctrl-S를 눌러 터미널 출력을 일시적으로 일시 중지할 수 없습니다. 개인적으로 마지막으로 의도적으로 사용한 것은 느린 모뎀 시절이었습니다. 요즘에는 빠른 스크롤링과 큰 스크롤백 버퍼의 출현으로 이 기능을 가끔씩만 사용한 다음 잠시 시간을 내어 눌러야 하는 것을 기억해야 합니다 Ctrl. Q그래야 터미널이 멈추지 않습니다. :)
답변2
사용이 스크립트. sqlite3
사용하려면 설치해야 합니다 . 데이터베이스를 업데이트하기 위해 서브셸에서 sqlite3을 시작합니다(디렉터리 변경이 평소만큼 빠릅니다 cd
). 디렉토리를 변경하려면 명령을 사용하여 이 스크립트를 다운로드하세요 source
. 인수가 제공되지 않으면 지난 이틀 동안 가장 많이 방문한 디렉토리의 정렬된 목록이 bash에 표시됩니다. 하나를 선택할 수 있습니다..bashrc
c
c