Wyświetl wszystkie pliki / pliki binarne w bieżącej ŚCIEŻCE

10

Czy istnieje „łatwy” sposób uruchomienia polecenia w stylu „ls -la” do wyświetlania wszystkich plików / plików wykonywalnych w bieżącej ścieżce?

(Zamierzam przesłać dane wyjściowe do grep, aby wyszukać polecenia z nieznanymi prefiksami, ale w zasadzie znanymi „nazwami”, rodzaj przypadku, gdy automatyczne uzupełnianie / tabulacja w bashu jest zasadniczo bezużyteczne. Więc coś w rodzaju „odwrotnego automatycznego pełna funkcja „...)

sme
źródło
Czy możesz podać przykłady? Czym się to różni ls -la?
John Siu
„ls -la” / „ls -a” wyświetla tylko pliki w bieżącym katalogu (pwd). Chcę wyświetlić listę wszystkich (wykonywalnych) plików we wszystkich katalogach zawartych w zmiennej PATH.
sme

Odpowiedzi:

19
compgen -c # will list all the commands you could run.
compgen -a # will list all the aliases you could run.
compgen -b # will list all the built-ins you could run.
compgen -k # will list all the keywords you could run.
compgen -A function # will list all the functions you could run.
compgen -A function -abck # will list all the above in one go. 
Nykakin
źródło
Fajnie, tego właśnie szukałem. Zawiera nawet wykonywalne pliki binarne w bieżącym katalogu. Dzięki.
sme
Działa dobrze ... w bash.
Emanuel Berg
czy istnieje sposób na wyświetlenie ścieżki każdego z nich bez robienia which $(compgen -A function -abck)?
h3rrmiller
Nie mogłem znaleźć lepszej alternatywy.
Nykakin,
3

Oto funkcja, która wyświetla zawartość katalogów $PATH. Jeśli przekazano argumenty, funkcja wyświetla tylko polecenia, których nazwa zawiera jeden z argumentów. Argumenty są interpretowane jako wzorce globalne.

shopt -s extglob
lspath () {
  local IFS pattern
  IFS='|'
  pattern="*@($*)*"
  IFS=':'
  for d in $PATH; do
    for x in "$d/"$pattern; do
      [ "$x" = "$d/$pattern" ] || echo "${x##*/}"
    done
  done | sort -u
}

Podobnie jak wiele rzeczy, jest to łatwiejsze w Zsh.

lspath () {
  (($#)) || set ''
  print -lr -- $^path/*$^@*(N:t) | sort -u
}

^Postacią rozszerzalności parametrów powoduje tekst łączone z tablicy być dodawane do każdego elementu tablicy, np path=(/bin /usr/bin); echo $^path/foonadrukami /bin/foo /usr/bin/foo.
/*$^@*wygląda jak obraza z komiksu, ale w rzeczywistości jest zwykłym znakiem /, symbolem wieloznacznym *, parametrem specjalnym $@(tablicą parametru pozycyjnego) z ^modyfikatorem i ponownie *.
(N:t)jest globalnym kwalifikatorem N do uzyskania pustego rozszerzenia, jeśli nie ma dopasowania, po którym następuje modyfikator historii, t aby zachować tylko basename („tail”) każdego dopasowania.

Bardziej tajemniczy, pozwala uniknąć połączenia zewnętrznego, ale ma to jedynie znaczenie kosmetyczne:

lspath () {
  (($#)) || set ''
  local names; names=($^path/*$^@*(N:t))
  print -lr -- ${(ou)names}
}

Być może faktycznie szukasz apropospolecenia, które wyszukuje strony podręcznika poleceń, których krótki opis zawiera słowo kluczowe. Ograniczeniem jest to, że znajdują się tylko polecenia, które mają stronę man.

Gilles „SO- przestań być zły”
źródło
W funkcji zsh druga ^wydaje się powodować brak wyjścia dla wywołania „bez argumentów”? Po upuszczeniu możesz wyświetlić je wszystkie i nadal wyszukiwać pojedyncze słowa kluczowe (ale nie ich listę). (Non:t)Zdaje się mówić, że gwiazdka powinna być rozszerzona? Nie mogłem wymyślić tego ostatniego.
Emanuel Berg
@EmanuelBerg Tak, dziękuję za poprawkę. Dodałem wyjaśnienie hałasu na linii.
Gilles „SO- przestań być zły”
OK, zobaczmy: Jeśli nie ma argumentów, ustaw „je” na nic, ponieważ to, co tam było (kiedy ich nie było), nadal w jakiś sposób zakłócało to, co zrobiłeś dalej? Ponadto, nigdy nie widziałem małych liter path, ale kiedy uruchamiam go w powłoce, jest to rzeczywiście $ PATH, ale ze spacjami zamiast :. Reszta jest krystalicznie czysta :)
Emanuel Berg,
@EmanuelBerg Nie: jeśli nie ma argumentów, ustawiam tablicę argumentów jako tablicę jednoelementową zawierającą pusty ciąg znaków. W ten sposób brak argumentów oznacza, że ​​każda nazwa zawierająca puste ciągi pasuje, tzn. Każda nazwa pasuje. $pathjest funkcją zsh: jest to parametr związany , tablica, która jest automatycznie aktualizowana, gdy PATHjest aktualizowana i na odwrót.
Gilles 'SO - przestań być zły'
Aha, teraz widzę! Wow, to było niekonwencjonalne!
Emanuel Berg,
1
function findinpath () { 
   OLDIFS="$IFS" ; 
   IFS="$(printf ':\t\n')" ; 
   for regexp in "$@" ; do 
      for adir in $PATH ; do 
         find "$adir" -perm -111 -a ! -type d -ls 2>/dev/null | grep -i "/[^/]*$regexp"
      done ; 
   done ; 
   IFS="$OLDIFS" ; 
}

znajdź tylko te pasujące, które: mają ustawiony co najmniej jeden bit „x” (wykonywalny) i nie jest to katalog.

i użyj go z listą wyrażeń regularnych, które można znaleźć:

findinpath awk sed '\.sh$'
Olivier Dulac
źródło
regexp „.” pokaże ci wszystko
Olivier Dulac
w zwykłym IFS można znaleźć zduplikowane wpisy w $ PATH:echo $PATH | tr ':' '\n' | sort | uniq -d
Olivier Dulac
1
Wypróbowałem kod dla wszystkich odpowiedzi i to jest jedyna, która faktycznie dała mi to, czego szukałem (pełne ścieżki do każdej instancji danego polecenia na ścieżce).
Chris Page
Cieszę się, że to pomogło :)
Olivier Dulac
1
for i in $(echo $PATH | sed -e 's/\:/\ /g'); do find "$i" -perm +rwx -exec echo {} \; 2> /dev/null; done

najpierw odbieramy echo $PATHw sed i zamieniamy „:” na „”.

następnie szukamy każdej z tych rzeczy, aby znaleźć pliki w rwx i je echo.

2> /dev/nulljest więc findnie będzie drukować błędów

h3rrmiller
źródło
3
potrzebujesz -maxdepth 1a -type fw swoim znalezisku, w przeciwnym razie znajdziesz podkatalogi i ich pliki (czego nie będzie szukać wyszukiwanie PATH). Poza tym twój test zgody jest dziwny - powinienem +xpomyśleć?
derobert
Nie będzie to obsługiwać przypadków na krawędziach, jeśli poprawny pusty wpis jest taki sam jak „.”, Na przykład :/binlub /bin::/usr/bin. Spróbuj dodać s/::/:.:/;s/^:/.:/;s/:$/:./do sedpolecenia.
Arcege,
W rzeczywistości findmożna wyszukiwać więcej ścieżek, więc możesz to zrobić bez pętli: find $(echo $PATH | sed -e 's/\:/\ /g') -perm +rwx …nazwy katalogów zawierające spacje zepsują go, ale i tak z tym problemem jest taka sama.
manatwork
@manatwork masz rację. Dodałem cytaty, aby rozwiązać ten problem właśnie
h3rrmiller
Przepraszam, to nic nie rozwiązuje. Problem polega na zastąpieniu dwukropków spacjami, aby umożliwić podział słów. Więc przekształcasz „/ foo bar: / fiz baz” w „/ foo bar / fiz baz”, a następnie przekazujesz to do for. Zapętli więc forlistę 4 słów. Manipulować słowem dzielenie lepiej ustawić IFSw zależności od potrzeb: IFS=':'; find $PATH -perm +rwx ….
manatwork