গ্লোব্বিংয়ের জন্য ব্যাশে কী সেটিংস রয়েছে, * ডট ফাইলের সাথে মেলে কিনা তা নিয়ন্ত্রণ করতে


12

আমি সম্প্রতি যখন আমি এমন কিছু করেছি mv ./* ../somedirectory এবং দেখলাম যে এর মতো ফাইলগুলি .gitignoreসরানো হয়নি।

আমি আমার বেশিরভাগ কাজ ওএস এক্সে জেডএসে করি, এবং এই চমকটি আমাকে সেন্টোসের উপর চাপিয়ে দেয়। আমি ওএস এক্সে বাশ দেওয়ার চেষ্টা করেছি এবং একই আচরণ পেয়েছি: *ডট ফাইলের সাথে মেলে না। এটি আমার কাছে খুব অবাঞ্ছিত বলে মনে হচ্ছে, তবে দৃশ্যত এটি ব্যাশ ডিফল্ট। (এটি আমার স্মরণে থাকা সমস্তগুলির জন্য zsh ডিফল্টও হতে পারে তবে আমার .zshrc এ আমি কয়েক বছর আগে এটি পরিবর্তন করেছি এবং ভুলে গিয়েছি যে এটি কখনও আলাদাভাবে কাজ করেছে))

আমি প্রত্যাশা মতো আচরণ করতে বাশকে কীভাবে কনফিগার করতে পারি: * সমস্ত ফাইলের সাথে মেলে, এবং ডট ফাইলগুলি উপেক্ষা না করে।

যদি বিষয়টি একেবারেই অস্পষ্ট থাকে তবে কীভাবে এটি পুনরুত্পাদন করা যায় তা এখানে

cd /tmp
mkdir {t,d}est
touch test/{.,}{1,2,3,4,5,6,7}
ls -hal test
mv test/* dest
ls -hal test     # notice dot files are still there
ls -hal dest     # notice only some files were mv'ed


হ্যাঁ, তারা সম্পর্কিত। আমি অনুসন্ধান করার সময় এটি প্রদর্শিত হয়নি (সম্ভবত কারণ এর প্রশ্নকারী প্রশ্নবিদ্ধ বা ডট ফাইলগুলি উল্লেখ করেনি) তবে এটি সত্যিই আলাদা প্রশ্ন really তিনি কীভাবে ফাইলগুলি স্থানান্তর করবেন জিজ্ঞাসা করছিলেন এবং আমি কীভাবে শেল আচরণ পরিবর্তন করতে এবং বিশেষত বাশার জন্য জিজ্ঞাসা করছিলাম। আমি যদি জিজ্ঞাসা না করতাম যে প্রশ্নটি আমার কাছে প্রদর্শিত হয়েছিল (যেহেতু আপনার চূড়ান্ত সম্পূর্ণ এবং পুঙ্খানুপুঙ্খ উত্তরটিতে ব্যাশ সেটিং অন্তর্ভুক্ত রয়েছে) তবে এটি এখনও অন্যরকম একটি প্রশ্ন, এবং আমার প্রশ্নের উত্তর খুঁজছেন এমন ব্যক্তি অবশ্যই খুঁজে পাচ্ছেন না তার প্রশ্ন।
আইকনোক্লাস্ট

এই পুরো "যে কেউ আমার প্রশ্নের উত্তর খুঁজছেন তা অগত্যা তার প্রশ্ন সন্ধান করতে পারে না" ব্যবসায়টি হ'ল আমাদের কেন ডুপ্লিকেট হিসাবে প্রশ্নগুলি বন্ধ করার এই উপায় রয়েছে।
গিলস 'অশুভ হওয়া বন্ধ করুন'

হ্যাঁ, তবে আপনি মূল বিষয়টি অনুপস্থিত মনে করছেন, এটি হ'ল এটি একটি আলাদা প্রশ্ন
আইকনোক্লাস্ট

উত্তর:


14

সজোরে আঘাত

আপনি ইতিমধ্যে লক্ষ্য করেছেন যে বাশ .নামের শুরুতে বা স্ল্যাশের সাথে কোনও মিলবে না । ডট সম্পর্কিত মিলটি পরিবর্তন করতে আপনাকে dotglobবিকল্পটি সেট করতে হবে - ম্যান বাশ :

ডটগ্লোব যদি সেট করা থাকে তবে ব্যাশে একটি with দিয়ে শুরু হওয়া ফাইলের নাম অন্তর্ভুক্ত রয়েছে `' ভিতরে
    পথের নাম প্রসারণের ফলাফল।

এটিকে বাশ ব্যবহার সহ সক্ষম / সেট করতে shopt, যেমন:

shopt -s dotglob


Zsh এর জন্য আপনি dotglobবিকল্পটিও ব্যবহার করতে পারেন তবে setoptএটি সক্ষম করতে আপনাকে ব্যবহার করতে হবে, যেমন:

setopt dotglob

2
এর সাথে zsh, আরও ভাল বিকল্পটি প্রতি গ্লোব ভিত্তিতে ডটগ্লোব সক্ষম করা :mv test/*(D) /dest
স্টাফেন চেজেলাস

7

আমি এটি পরীক্ষা করেছি এবং এটি সমস্যার সমাধান করে:

shopt -s dotglob

আউটপুট:

~/stackexchangeanswers/40662$ ls -hal dest
total 8.0K
drwxr-xr-x 2 jodiec jodiec 4.0K 2012-06-12 22:15 .
drwxr-xr-x 4 jodiec jodiec 4.0K 2012-06-12 22:15 ..
-rw-r--r-- 1 jodiec jodiec    0 2012-06-12 22:15 1
-rw-r--r-- 1 jodiec jodiec    0 2012-06-12 22:15 .1
-rw-r--r-- 1 jodiec jodiec    0 2012-06-12 22:15 2
-rw-r--r-- 1 jodiec jodiec    0 2012-06-12 22:15 .2
-rw-r--r-- 1 jodiec jodiec    0 2012-06-12 22:15 3
-rw-r--r-- 1 jodiec jodiec    0 2012-06-12 22:15 .3
...snipped....

দুঃখিত তবে উলরিচ প্রথমে উত্তর দিলেন।
আইকনোক্লাস্ট

3
আমরা সবাই একই দলে আছি। ঠিক আছে.
Jodie সি

6

*শেল দ্বারা প্রসারিত একটি গ্লোব হয়। ডিফল্ট শেলগুলি এমন ফাইলগুলিকে অন্তর্ভুক্ত করে না যার নাম শুরু হয় .(যাকে বলা হয় লুকানো ফাইল বা ডটফিলস) যদি না নেতৃস্থানীয় .আক্ষরিক প্রবেশ না করে ।

*বা [.]*বা ?*বা *.*বা dir/*dotfiles অন্তর্ভুক্ত করবে না।

.*বা dir/.*হবে।

সুতরাং আপনি করতে পারেন:

mv -- * .* /dest/

তবে কিছু শাঁস সহ bash(তবে তা নয় zsh, mkshনা fish) এই অপব্যবহার রয়েছে যে প্রসারিত প্রসারণটি এবং বিশেষ ডিরেক্টরি এন্ট্রিগুলি .*অন্তর্ভুক্ত রয়েছে , যা আপনি এখানে চান না (এবং সাধারণত কোনও গ্লোবও অন্তর্ভুক্ত করতে চান না যার কারণে আমি এটিকে অপব্যবহার বলি)।...

সেই কারণে আপনি দেখতে পাবেন যে কখনও কখনও লোকেরা ব্যবহার করে (বোর্নের মতো শেলগুলিতে):

mv -- * .[!.]* ..?* /dest/

এটি তিনটি গ্লোব, প্রথমটি নন-লুকানো ফাইলগুলির সাথে মিলিত, দ্বিতীয় একটি ফাইলের নাম এবং তার পরে .অন্য একটি অক্ষর .এবং তৃতীয় একটি ফাইলের নাম ..অন্তত একটি অক্ষর দ্বারা শুরু হওয়া ।

তবে কিছু আধুনিক শেলগুলির কাছাকাছি আরও ভাল উপায় রয়েছে

zsh

এর সাহায্যে zshআপনি (D)গ্লোব কোয়ালিফায়ার ব্যবহার করে গ্লোবটিতে ডটফাইলগুলি অন্তর্ভুক্ত করা উচিত তা নির্দিষ্ট করতে পারেন :

mv -- *(D) /dest/

zshএছাড়াও বোর্ন শেলের অন্য ভুল বৈশিষ্ট্য এটি ঠিক করেছে যে প্যাটার্নটি মেলে না, mvকমান্ডটি চালানো হয় না।

যেমন উপরে বলা হয়েছে এটি কখনও অন্তর্ভুক্ত করবে না .বা ..তার গ্লোবগুলিতেও তাই হবে না

mv -- * .* /dest/

নিরাপদ হবে। তবে, যদি কোনও ফাইলের মিল নেই *বা .*কমান্ডের সাথে মেলে কোনও ফাইল বাতিল করা হবে, সুতরাং এটি ব্যবহার করা ভাল:

mv -- (*|.*) /dest/

অন্য কয়েকটি শেলের মতো আপনিও সমস্ত গ্লোবগুলিকে ডটফাইলগুলি অন্তর্ভুক্ত করতে বাধ্য করতে পারেন (উদাহরণস্বরূপ যদি আপনি নিজেকে ডটফাইলগুলি প্রায়শই অন্তর্ভুক্ত করতে চান তবে) এর সাথে:

setopt dotglob

বা:

set -o dotglob

এর পরে, আপনি যদি কোনও নির্দিষ্ট গ্লোব ডটফিলগুলি অন্তর্ভুক্ত না করতে চান তবে আপনি এটি লিখতে পারেন:

echo *(^D)

বা:

echo [^.]*

সজোরে আঘাত

দুর্ভাগ্যক্রমে bashগ্লোব কোয়ালিফায়ার নেই। সুতরাং আপনি বিশ্বব্যাপী ডটফিল অন্তর্ভুক্তি সক্ষম করে রেখেছেন। ইন bash, বাক্য গঠনটি হ'ল:

shopt -s dotglob

(এবং [^.]*লুকানো ফাইল ছাড়াই গ্লোবগুলির জন্য ব্যবহার করুন )।

সঙ্গে dotglob, bashঅন্তর্ভুক্ত না .কিংবা ..মত globs মধ্যে *, কিন্তু এখনও মত globs জন্য করে .*

আপনি সেট করেন তাহলে GLOBIGNOREকিছু খালি নয় এমন পরিবর্তনশীল, এটা তখন স্বয়ংক্রিয়ভাবে সক্ষম dotglobবিকল্প এবং বাদ .এবং ..থেকে .*globs কিন্তু থেকে dir/.*বা .*/fileবেশী (!) যাতে রক্ষাকবচ চমত্কার অনর্থক। আপনি কাজ করতে পারে GLOBIGNORE='*/.:*/..:./*:../*:*/./*:*/../*'কিন্তু তারপর এটা পছন্দ globs বিরতি দেবে */.বা ./*অথবা ../*

একটি ভাল কাজ প্রায় ব্যবহার করা [.]*বা dir/[.]*বা [.]*/file(সঙ্গে dotglobসক্ষম করা থাকে) ব্যতীত dotfiles প্রসারিত করতে .এবং ..

মাছ

fishগ্লোবগুলিও অন্তর্ভুক্ত .নয় ..। সংস্করণের উপর নির্ভর করে কোনও মিল নেই, তখন এটি zsh(বা bash -o failglob) বা এর মতো কাজ করবে bash -o nullglob

mv -- * .* /dest/

যদি লুকানো এবং গোপন না থাকা উভয় ফাইলই কাজ করে। অন্যথায়, ওয়াইএমএমভি এবং কিছু সংস্করণ সহ, mv -- /destকোনও ফাইল না থাকলে এটি কল করতে পারে ।

ksh93

ksh93উভয়ই গ্লোব কোয়ালিফায়ার । আপনি গ্লোবগুলিতে ডটফাইলগুলি এর সাথে অন্তর্ভুক্ত করতে পারেন:

FIGNORE='@(.|..)'

পক্ষান্তরে bashএর GLOBIGNORE, যে সঠিকভাবে সম্পন্ন এবং এর সমস্যা সমাধান করা হয়েছে .*সহ .এবং ..

যশ

yashএকটি dot-globবিকল্প আছে ( set -o dot-glob), কিন্তু এর বিপরীতে bash, গ্লোব সম্প্রসারণ (এমনকি এর *) এর অন্তর্ভুক্ত রয়েছে .এবং ..তাই এটি বেশ অকেজো।

tcsh শেল

set globdot

মধ্যে মত কাজ করে bash, অর্থাৎ *ব্যতীত ডট ফাইল অন্তর্ভুক্ত .এবং ..কিন্তু .*এখনও রয়েছে .এবং ..(এবং আপনি ব্যবহার করতে পারেন [.]*ব্যতীত লুকানো ফাইল প্রসারিত করতে .এবং ..)।


4

ম্যাচিং ডট ফাইলগুলি মুছে ফেলার জন্য ব্যাশের সহজতম উপায়, উপেক্ষা করা .এবং ..তা:

$ GLOBIGNORE=/+/
$ printf '%s\n' *


পরীক্ষা করার জন্য:

$ cd tmp; mkdir empty; cd empty; touch {,.}{a..h}
$ GLOBIGNORE=/+/
$  ls *
a  .a  b  .b  c  .c  d  .d  e  .e  f  .f  g  .g  h  .h

এটা উল্লেখযোগ্য ব্যতিক্রম বিন্দু বা না দিয়ে সব ফাইল মুদ্রিত, .এবং ..

আপনার উদাহরণটিও সঠিকভাবে কাজ করবে:

$ cd /tmp; mkdir {t,d}est; touch test/{,.}{a..h}
$ mv test/* dest/
$ ls -a test
.  ..
$ ls -a test/*
ls: cannot access test/*: No such file or directory

ফাইলগুলির খালি বিষয়।
সিস্টেম ফাইলগুলি . ..এখনও বিদ্যমান তবে শেল প্রসার (* ব্যবহার করে) এগুলিকে অন্তর্ভুক্ত করবে না।

এবং ডেসট ইনশন ডিরেক্টরিতে সমস্ত ফাইল রয়েছে:

$ cd dest
$ ls -a *
a  .a  b  .b  c  .c  d  .d  e  .e  f  .f  g  .g  h  .h

কেন?

এটি কাজ করে কারণ গ্লোবিগনরে সেট করার এই পার্শ্ব প্রতিক্রিয়া রয়েছে:

  • shopt -s dotglobবিস্তারে গণিত ডট ফাইলগুলিতে ডটগ্লোব ( ) সেট করুন।
  • ফাইলের নাম . এবং ..GLOBIGNORE সেট করা থাকলে এবং শূন্য না হয়ে এড়ানো হয়।

ম্যানুয়াল বিবরণ: LESS=+'/The GLOBIGNORE' man bash

এছাড়াও, কোনও ফাইল নাম মেলে না এমন একটি নাম রাখতে আমাদের চলক গ্লোবিগনোর সেট করতে হবে:
একটি স্ল্যাশ (এবং ডাবল সাবধানতা হিসাবে ঠিক অন্য কোনও কিছু)।

$ GLOBIGNORE=/+/

নালাগ্লাব সেট করাও কার্যকর হতে পারে যদি এটির সাথে মিলানোর *জন্য কোনও ফাইল নেই যখন একটি পাওয়া এড়ানো প্রয়োজন হয় *


0

GLOBIGNORE = / + / @ ব্যবহারকারীর79743 এর এই সেটিংটি খুব আগ্রহী

আমার অভিজ্ঞতা থেকে unsetting dotglob হয় খারাপ ব্যবসা প্রায় সব আপনার কমান্ড (CP এম ভি ইত্যাদি) কিন্তু একই সত্য থেকে সেটিং nullglob (বিশেষ করে নিয়মিত এক্সপ্রেশন যে তারপর পলায়নের প্রয়োজন!)।

তবুও, যদি আপনার প্রোগ্রামের শুরুতে এগুলি সেট করার প্রয়োজন হয় তবে নির্দিষ্ট অংশগুলিতে হস্তক্ষেপ করুন যেখানে আপনি কমান্ডগুলি সিপি, এমভি ইত্যাদিতে কল করেন বা নিয়মিত এক্সপ্রেশন ব্যবহার করেন কেবল এটি করুন:

  # set dotglob, unset nullglob AFTER this
  is_nullglob=$( shopt -s | egrep -i '.*nullglob' )
  is_dotglob=$( shopt -s | egrep -i '.*dotglob' )
  [[ $is_nullglob ]] && shopt -u nullglob
  [[ ! $is_dotglob ]] && shopt -s dotglob
  # ... call commands ...
  # .....................
  # reset dotglob, nullglob to their previous values
  [[ $is_nullglob ]] && shopt -s nullglob
  [[ ! $is_dotglob ]] && shopt -u dotglob
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.